Introduction to the Windows CE Device Driver Kit

Like other operating systems, Windows CE implements software called device drivers, whose purpose is to interface with, or drive, built-in and peripheral hardware devices. A device driver links an operating system and a device, making it possible for the operating system to recognize the device and to present the device’s services to applications.

Windows CE supports a wide range of device drivers that you can customize for various Windows CE–based platforms. Windows CE also provides several models for driver development, including driver models from other operating systems. Because of this diversity of driver models, Windows CE accommodates almost any conceivable type of device, either as a built-in or as a peripheral device.

The Microsoft Windows CE Device Driver Kit supplies documentation enabling you to create device drivers for Windows CE. Currently, Windows CE offers four device driver models, two that are unique to Windows CE and two that are external models adapted from other operating systems. The two Windows CE–based models are the native device driver and the stream interface driver. The two external models are designed for universal serial bus (USB) drivers and network driver interface specification (NDIS) drivers.

The various driver models are differentiated only by the software interface that they support and not by the devices that they serve. The driver model determines the software interface that any given driver exports. Independent of the driver model, a device driver may either be monolithic or layered, meaning that it can implement its software interface directly in terms of actions on the device or separate the implementation of the software interface and the actions on the device into two layers. Many of the sample drivers provided by Microsoft use this layered organization because it reduces the amount of code that developers must write when porting the sample drivers to new devices. Device drivers can access their devices directly if the devices are mapped into system memory, or they may need to use the services of lower-level device drivers in order to access their devices. For example, device drivers for PC Card devices need to use the services of the PC Card socket driver to access PC Card devices. Finally, device drivers may be interrupt-driven, may be polled, or may not require status updates from their devices.

As their name suggests, native device drivers serve devices that are integral to a Windows CE–based platform. Native device drivers are designed specifically for low-level built-in hardware, such as keyboards, screens, and PC Card sockets. Because native device drivers generally have a strong connection to Windows CE–based platforms and each type of native device driver has a precise, specialized purpose, Microsoft provides support for native device drivers in the form of custom interfaces. This means that the majority of developers do not need to write native device drivers. The exceptions are OEMs who customize Windows CE for new platforms. They can either create their own native device drivers or port Microsoft sample native device drivers to their Windows CE–based platform. Native device drivers are always loaded when the Windows CE–based platform boots.

In contrast to native device drivers, which have custom interfaces, stream interface drivers are a generic type of device driver. Stream interface drivers are user-level dynamic-link libraries (DLLs) that implement a fixed set of functions, the stream interface functions, enabling an application to interact with a device through special files in the file system. Stream interface drivers support almost any kind of peripheral device that can be attached to a Windows CE–based platform. For example, developers have designed stream interface drivers to support a variety of peripherals, including pagers, printers, modems, bar-code scanners, and Global Positioning System (GPS) receivers.

The stream interface functions enable applications to interact with a device through special files in the file system. OEMs can also create stream interface drivers to serve devices that are designed as part of a Windows CE–based platform when Microsoft has not defined a specific interface for a particular type of device. For example, a Windows CE–based point-of-sale system might have a bar-code scanner built into the hardware of the system, but because Microsoft has not yet defined a custom interface for bar-code scanners, the device driver for the scanner would be a stream interface driver, rather than a native device driver.

Some common types of built-in devices, such as serial ports, use stream interface drivers because the functionality of the devices is well suited to the structure of a stream interface driver. OEMs sometimes write a few stream interface drivers for this reason. Peripheral manufacturers are responsible for providing stream interface device drivers so that their peripherals can be used with Windows CE.

A USB driver connects USB-compliant devices to Windows CE. Unlike stream interface drivers, however, USB drivers are not required to export any particular set of functions to applications. Depending on the device, a USB driver can export the stream interface functions, export a custom set of functions, or use existing Windows CE APIs to expose the functionality of the device. Using existing Windows CE APIs is appropriate for a pointing device or a mass-storage device, neither of which applications need to use directly. Windows CE has existing mechanisms, the input-event system and the Block Device Driver API, respectively, for managing these types of resource.

NDIS drivers are adapted from the Microsoft Windows NT® operating system. The NDIS driver is a driver model that enables networking protocols, such as the TCP/IP and the Infrared Data Association (IrDA) protocol, to be completely independent of the implementation details of device drivers for network interface cards (NICs).

The following illustration shows the current collection of driver models and device drivers.

The remainder of this guide explains in detail how to implement the device driver models.

The Device Driver Kit is packaged with two different products, the Microsoft® Windows® CE Platform Builder, which contains source code and libraries for OEMs who build custom Windows CE–based platforms, and the Windows CE Platform SDK, which contains the cross-compiler tools and libraries necessary to build software for Windows CE–based platforms. In addition, the Platform Builder includes source code for a number of sample device drivers.


Developing Native Device Drivers

To port Windows CE to a target platform, you must provide device drivers for the devices built into your platform. Some types of devices—such as keyboards, displays, and PC Card sockets—have a custom interface to the operating system. The drivers for these types of devices are called native device drivers because the interfaces they use are specific to Windows CE.

In general, native device drivers are of interest only to original equipment manufacturers (OEMs) who build Windows CE–based platforms. Independent hardware vendors (IHVs) who develop drivers for add-on hardware have no need to design or customize native device drivers. Therefore, the following sections regarding native device drivers are directed primarily to OEMs.

Microsoft defines custom interfaces for each type of native device driver. However, although each type of native device driver has a custom interface, native device drivers present a standard set of functionality for all devices of a particular class. This enables the Windows CE operating system to treat all instances of a particular device class alike, despite any physical differences. For example, many Windows CE–based platforms use some type of LCD panel as their displays. However, there are a wide variety of these panels on the market, which have different operating characteristics, such as resolution, bit depth, memory interleaving, and so on. By making all display drivers conform to the same interface, Windows CE can treat all display devices the same, regardless of the physical differences between the devices themselves.

Typically, OEMs link native device drivers with the Graphics, Windowing, and Events Subsystem (GWES) module when they build custom Windows CE–based platforms. However, there are exceptions; not all native device drivers are linked with GWES during the build process. For example, users install and load some types of native device driver, such as display drivers and printers.

For a Handheld PC (H/PC), sample native device drivers are available for the various device classes built into the platform. These device classes are the following:

  • Display
  • Battery
  • Keyboard
  • Touch screen
  • Notification LED
  • PC Card socket

If your target platform contains a set of devices different from those on the H/PC, you need to create your own native device drivers for the devices. However, if your platform includes devices similar to those on the H/PC, consider porting the sample native device drivers, which the Windows CE Platform Builder provides, to your platform, rather than developing your own native device drivers. By porting the tested device drivers, you can save time and avoid bugs. Even so, it is not mandatory to use the sample code provided with the Platform Builder for the native device driver or for any other driver model. The Platform Builder supplies driver samples solely as a convenience to help you develop your drivers rapidly.

The following sections provide information about native device drivers to help you use and modify the driver models supplied in the Platform Builder. These sections discuss the following:

  • System architecture for native device drivers
  • Restrictions on what native device drivers can do and what system APIs they can call
  • Handling of interrupt events in a native device driver
  • Porting of sample native device drivers to your platform

Note Directory and paths listed are relative to the root directory of the Platform Builder installation.


System Architecture for Native Device Drivers

The sample device drivers included with the Platform Builder come in two types: monolithic and layered. A monolithic driver, as the name implies, is based on a single piece of code that exposes the functionality of the hardware device to the operating system directly. In contrast to the monolithic driver, the layered driver consists of two customized layers: the upper layer is the model device driver (MDD), and the lower layer is the platform-dependent driver (PDD). Most of the sample device drivers are configured as layered, rather than monolithic.

The following illustration shows the integration of monolithic and layered drivers within the Windows CE operating system.

Microsoft provides the MDD for a layered driver. The MDD is common to all platforms and functions, both as source code and as a library. It performs the following tasks:

  • Links to the PDD layer and defines the functions it expects to call in that layer.
  • Exposes different sets of functions to the operating system.
  • Handles complex tasks, such as interrupt processing.
  • Communicates with the GWES module and with the kernel.

Each MDD also handles a specific set of devices, such as audio hardware or touch screens.

In general, the MDD requires no changes. If you choose to modify the MDD, be aware that Microsoft does not test, warrant, or support custom MDDs. You are responsible for all further MDD maintenance if Microsoft supplies an updated MDD in order to fix bugs or to support later versions of Windows CE. In addition, if you revise the MDD you must provide support to any IHVs who use those changes.

Unlike the MDD layer, the PDD layer, which interfaces with both the MDD and the hardware, is meant to be tailored to your target platform. A PDD consists of hardware-specific functions that correspond to an MDD. There is no direct one-to-one relationship between the functions in a PDD and the corresponding MDD; the MDD functions implement discrete tasks that the MDD uses to achieve its goals. Because the PDD is hardware-dependent, you must create a customized PDD and port it to your platform hardware. To assist you, Microsoft provides several sample PDD layers for various built-in devices.

You can forego the MDD and PDD layers by implementing your device driver as a monolithic driver. For example, if performance is a critical factor, a monolithic driver might be a better choice than a layered driver because a monolithic driver avoids the overhead associated with the function calls that take place between the MDD and PDD layers. You might also choose to implement a monolithic driver if the capabilities of the device in question are well matched to the tasks that the functions in the MDD layer perform. In such a case, implementing a monolithic driver might be simpler and more efficient than implementing a layered driver. However, regardless of whether you implement a monolithic driver or a layered driver, you can base your implementation on the source code for any of the sample layered drivers.

As shown in the previous illustration, the device driver interface (DDI) is a set of functions implemented in the MDD and called by the GWES module; the device driver service-provider interface (DDSI) is a set of functions implemented in the PDD and called by the MDD. Use DDI functions for monolithic drivers and DDSI functions for layered drivers.

Finally, some of the sample device drivers are implemented as stream interface drivers, which means that the drivers use the stream interface as their DDI. In this case, you do not need to link such drivers with the GWES module. They exist as ordinary DLLs and are loaded as needed. The audio driver is an example of a device driver using the stream interface model. Because these drivers have an MDD and PDD that you can use as a basis for your development efforts, they are included here, in the native device driver section, rather than in Developing Stream Interface Device Drivers.


Restrictions on Native Device Drivers

Device drivers are user-level processes, which means that the driver code can call Microsoft® Win32® APIs and access any resources available to user-level processes. For the most part, though, device drivers need only a limited number of simple APIs, such as memory allocators. Drivers do occasionally perform more complex tasks, including creating threads or windows. For example, on many Windows CE–based platforms, the battery driver presents a dialog box to users when the batteries drop below a threshold voltage, thus notifying users to replace the batteries.

The only time a driver cannot call Win32 APIs is when the driver processes a notification that the device is shutting down. In this situation, the device driver must not perform any operations that might cause a context switch. For example, if the driver attempts to open a file during this time, the kernel might need to access the file system, swap pages out of memory, and use other system resources that might depend on separate execution contexts. To avoid these problems, restrict the device driver to the following actions when shutting down:

  • Saving the device state in pre-allocated storage
  • Issuing any commands to the device pertinent to shutting down
  • Setting a flag within the driver to note that it has been shut down

When power returns, the driver can restore the device state from the saved information.

The driver can also use the SetInterruptEvent function to generate an artificial interrupt event. By calling SetInterruptEvent, a driver can force release of the interrupt thread to continue any necessary processing. For examples of using SetInterruptEvent, see the HWPowerOn and HWGetIntrType functions in the P2io.c file. Drivers should call these functions only during suspend and resume processing.


Interrupt Handling in Native Device Drivers

Like many other computer architectures, Windows CE–based platforms use interrupts to signal the operating system when devices need servicing by their drivers. For example, when a user presses a key or taps a screen, the keyboard hardware or the touch screen generates an interrupt.

However, Windows CE does not support nested interrupts, meaning that interrupts cannot occur simultaneously. Processing of one interrupt must finish before another begins. Although this limits the real-time scheduling capabilities of Windows CE, it vastly simplifies the process of writing interrupt handlers.

Windows CE balances performance and ease of implementation by breaking interrupt processing into two parts, a kernel-mode part and a user-mode part. The kernel-mode part is called the interrupt service routine (ISR), and the user-mode part is called the interrupt service thread (IST). The ISR is the part that cannot be nested; therefore, keep your ISRs short and fast so that interrupts are disabled as little as possible. The ISR resides in the OEM adaptation layer (OAL) and has direct access to hardware registers. Its sole job is to determine which interrupt identifier, such as SYSINTR_SERIAL, to return to the kernel interrupt handler. Essentially, ISRs map physical interrupts onto logical interrupts. Platform-independent interrupt identifiers are declared in the Nkintr.h header file, and platform-specific interrupt identifiers are declared in platform header files, such as Platform\Cepc\Inc\Oalintr.h.

Because an ISR is small and does very little processing, the interrupt handler calls an IST to perform the bulk of processing required to handle an interrupt. The IST remains idle until it receives a signal from the WaitForSingleObject function that an interrupt has occurred. When an IST receives the signal, it calls subroutines in the PDD layer of the native device driver; these routines in turn access the hardware to retrieve information or to set the hardware state. The IST is a standard secondary thread that can be pre-empted and scheduled by the operating system. However, to enhance real-time performance, Windows CE uses the two highest thread-priority levels, THREAD_PRIORITY_HIGHEST and THREAD_PRIORITY_TIME_CRITICAL, for ISTs. These priority levels are not reserved for ISTs; any secondary thread can also have those priority levels.

On a Windows CE–based reference platform, which uses the Hitachi SH3 microprocessor, the system can start an ISR in 2 to 5 microseconds. The system can start the corresponding IST in 90 to 170 microseconds. Many actual Windows CE–based platforms have better response times than these, depending on factors such as CPU type, clock speed, bus speed, and so on. Aside from hardware performance, the IST start times vary from one interrupt event to the next due to unpredictable factors, such as the state of the processor cache and whether the IST happens to be the currently running thread.

If your platform is not meeting your real-time performance requirements, you have the following options:

  • Putting more processing into the ISR. This is strongly discouraged because when an ISR is running, no other threads are scheduled, and interrupts are masked. A user might experience poor performance of the device or missed input if an ISR takes very long.
  • Adding buffering hardware that can store information relevant to several interrupt events and modifying the IST so that it gathers the information from several interrupt events in the buffering hardware. This enables the IST to process interrupts in batches, resulting in a reduction of real-time requirements.
  • Using a higher clock frequency on the CPU, on the data bus, or on both.
  • Adjusting the priorities of the platform ISTs.

The following illustration shows the interaction of components during the interrupt process.

The exception handler is the primary target of all interrupts. When an interrupt occurs, the kernel jumps directly to the exception handler. The exception handler then calls whichever ISR is registered to handle the current interrupt.

OEMs register their ISRs with the exception handler at startup time. First, the kernel calls the OEMInit function in the OAL. Next, OEMInit calls the HookInterrupt function to inform the exception handler of which ISRs correspond to individual physical interrupt lines. A few subroutines in the OAL, such as the OEMInterruptEnable, OEMInterruptDisable, and OEMInterruptDone functions, are also used in interrupt processing.

The interrupt handler manages the details of registering a driver for a particular interrupt and deregistering it later. It also maintains communication among the ISR, the IST, and subroutines within the OAL.

Monolithic drivers can use the Interrupt Event Handler Support interface provided by the kernel. This interface is a lightweight process-synchronization model based on standard Win32 events. The interface consists of event-related functions, such as CreateEvent, SetEvent, ResetEvent, and WaitForSingleObject, and the Windows CE kernel InterruptDone, InterruptDisable, InterruptEnable, and InterruptInitialize functions. Layered drivers use the same functions to process interrupts, but you need not use these functions to port layered drivers because the MDD layer—which does not require modification—already contains the proper calls to these functions.

The following sections discuss in greater detail how to register an interrupt handler, process it, and deregister it.


Registering an Interrupt Handler

After a native device driver is loaded, the driver creates an IST and registers it with the interrupt handler. The IST is registered for one or more logical interrupts.

If you use the existing MDD implementation for a particular driver, the MDD layer registers the driver for interrupts. If you write a monolithic driver, you need to implement code for registering the IST of the driver with the interrupt handler. To do this, use the InterruptInitialize function to create an event and associate it with an interrupt identifier.


Processing an Interrupt

A specific sequence of events takes place when an interrupt is processed. You should write the ISR and IST for your native device driver with the following sequence of events in mind:

  1. When an interrupt occurs, the kernel jumps to the exception handler.
  2. The exception handler disables all interrupts and calls the appropriate ISR for the physical interrupt line.
  3. The ISR returns a logical interrupt, in the form of an interrupt identifier, to the interrupt handler.
  4. The interrupt handler re-enables all interrupts, with the exception of the current interrupt, and signals the appropriate IST.
  5. The IST calls PDD routines to access the hardware and finish processing the logical interrupt.
  6. The IST calls the InterruptDone function.
  7. The interrupt handler re-enables the current interrupt and calls the OEMInterruptDone function in the OAL.


Deregistering an Interrupt Handler

If a device driver needs to stop processing an interrupt, the driver must use the InterruptDisable function. When the driver calls this function, the interrupt handler removes the association between the IST and the specified logical interrupt. The interrupt handler accomplishes this by calling the OEMInterruptDisable function to turn off the interrupt. The driver can register for the interrupt again later, if necessary.


Porting the Sample Native Device Drivers

To port Windows CE to a target platform, you must provide drivers for built-in devices, such as keyboards, touch screens, PC Card sockets, serial ports, and audio hardware.

To assist you with the porting procedure, the following sections contain descriptions of sample MDD and PDD implementations provided with the Platform Builder. The actual samples appear under the Platform\ODO\Drivers and Platform\ODO\GWE subdirectories of your installation. The following sections also list the DDI and DDSI functions related to the sample drivers; any native device driver you write should use or implement the same DDI or DDSI functions, depending on whether you write a monolithic or a layered device driver:

  • Sample Battery Driver
  • Sample Display Driver
  • Sample Keyboard Driver
  • Sample Notification LED Driver
  • Sample PC Card Socket Driver
  • Sample Serial Port Driver
  • Sample Touch Screen Driver
  • Sample USB Host Controller Driver


Sample Battery Driver

The battery driver provides information about the power level of the battery supply of a platform. The battery driver reports main battery status and backup battery status, assuming that a platform has both. The battery driver is statically linked to GWES, so it does not exist as a DLL. The battery driver sample code is under \Platform\ODO\GWE\Battery.

The battery driver is a monolithic driver, and hence uses only DDI functions. The following table shows the DDI functions for the battery driver.

BatteryDrvrGetLevels
BatteryDrvrGetStatus
BatteryDrvrSupportsChangeNotification


Sample Display Driver

The display driver controls all writing to the built-in display hardware of the system. Typically, this is an LCD screen, but it can be any sort of display hardware that is suitable to your target platform. In Windows CE 2.0 and later, the display driver model for built-in display hardware is the same as the model for peripheral display adapter drivers.

By default, Windows CE uses built-in display hardware that cannot be removed by a user. Windows CE can also use removable peripheral display adapters, usually in the form of PC Cards. For either type, your display driver DLL must be named Ddi.dll.

Create a registry key under HKEY_LOCAL_MACHINE\Drivers\Display to store configuration entries for your display driver. In addition, the initialization routine of your display driver should create keys under HKEY_LOCAL_MACHINE\Drivers\Display\Active so that applications can determine which display devices are available.


Sample Keyboard Driver

The keyboard driver converts input from the keyboard hardware into keyboard events that are fed into the input system. Next, the driver generates the proper Unicode characters from these keyboard events. The Platform Builder includes a keyboard driver that is divided into blocks, which facilitates development of keyboard drivers for international keyboard layouts. This driver can be found under \Platform\ODO\Drivers\Keybd2.

The keyboard driver contains two functions, ScanCodeToVKeyEx and KeybdDriverVKeyToUnicode, that control how keyboard scan codes are translated into virtual keys and Unicode characters. These functions are based on translation tables, which can be customized for different languages. For translation tables for Brazilian Portuguese, Dutch, French, German, Italian, Japanese, Portuguese, Spanish, Swedish, UK English, and US English, see Keyboard Mapping. You can create your own translation tables or customize the existing tables, if necessary.

The sample code shows a design that works for the standard Windows CE–based keyboard layout. By replacing the PDD layer, developers have implemented drivers for hardware that uses software scanning, hardware scanning, and a dedicated keyboard controller. Unusual hardware or nonstandard keyboard layouts might require modification of both the MDD and PDD layers. You can change the MDD layer to build a custom Keybdmdd.lib. Source code for the MDD layer is located under \Public\Common\Oak\Drivers.

The Windows CE input system loads the keyboard driver at startup time. When the input system starts, it retrieves the name of the keyboard driver DLL from the HKEY_LOCAL_MACHINE\Hardware\DeviceMap\KEYBD\Drivername registry key. If no entry is found, the input system uses the default name, Keybddr.dll. It then loads the DLL and verifies that all required entry points exist.

Next, the input system calls the KeybdDriverInitialize function to perform a one-time initialization. In this function, the MDD saves a local copy of the input system callback function. The MDD also calls the KeybdPdd_InitializeDriver function, which starts a thread to handle keyboard interrupts, and then returns to the input system.

In the sample MDD, the IST of the keyboard driver is named KeybdDriverThread. This thread calls the InterruptInitialize function to register for the SYSINTR_KEYBOARD interrupt, and then waits for the system to issue SYSINTR_KEYBOARD signals. When it receives those signals, the interrupt handler calls the KeybdPdd_GetEvent function. The interrupt handler sends the key events returned from the PDD to the input system, which queues them for distribution to applications.

When the input system pulls the keyboard event from the queue, it invokes a callback to the driver’s KeybdDriverVKeyToUnicode routine. The driver analyzes the specified key event and the virtual key state and generates the corresponding characters. The input system then sends the virtual key and the characters to the appropriate application.

The KeybdDriverGetInfo and KeybdDriverSetMode functions get and set information about the keyboard. When the main input thread processes a keyboard-connection event, the thread calls the KeybdDriverGetInfo function to get the virtual-key-to-Unicode data supplied by the driver. The thread also allocates the required memory for the virtual key state data and any extra data required by the driver. Next, it calls the KeybdDriverInitStates function to initialize the memory.

The following table shows the DDI functions for the keyboard driver.

KeybdDriverGetInfo | KeybdDriverSetMode
KeybdDriverInitialize | KeybdDriverVKeyToUnicode
KeybdDriverInitStates | KeybdEventCallback
KeybdDriverPowerHandler |

The following table shows the DDSI functions for the keyboard driver.

KeybdPdd_DllEntry
KeybdPdd_GetEvent
KeybdPdd_InitializeDriver
KeybdPdd_PowerHandler


Sample Notification LED Driver

The notification LED driver handles all requests to turn the system notification LED on or off. These include queuing notification events, waiting until those events have elapsed, and getting and setting user-notification preferences. The sample notification LED driver code appears under \Platforms\ODO\GWE\Nleddrv.

The following table shows the DDI functions for the notification LED driver.

CeClearUserNotification
CeHandleAppNotifications
CeRunAppAtEvent
CeRunAppAtTime
CeSetUserNotification

The following table shows the DDSI functions for the notification LED driver.

NLedDriverDllEntry
NLedDriverGetDeviceInfo
NLedDriverInitialize
NLedDriverPowerDown
NLedDriverSetDevice


Sample PC Card Socket Driver

The PC Card socket driver manages any PC Card sockets on a Windows CE–based platform. The MDD layer of this driver exposes a number of functions that can be used to write stream interface drivers for individual PC Cards. These functions constitute the Card Services library. The PDD layer exposes a set of lower-level functions that the MDD layer uses. These functions constitute the Socket Services library. The sample PC Card driver code appears under \Platform\ODO\Drivers\Pcmcia.

The following table shows the DDI functions for the PC Card socket driver.

CardAccessConfigurationRegister | CardReleaseExclusive
CardDeregisterClient | CardReleaseIRQ
CardGetEventMask | CardReleaseSocketMask
CardGetFirstTuple | CardReleaseWindow
CardGetNextTuple | CardRequestConfiguration
CardGetParsedTuple | CardRequestExclusive
CardGetStatus | CardRequestIRQ
CardGetTupleData | CardRequestSocketMask
CardMapWindow | CardRequestWindow
CardModifyWindow | CardResetFunction
CardRegisterClient | CardSetEventMask
CardReleaseConfiguration |

The following table shows the DDSI functions for the PC Card socket driver.

PDCardGetAdapter | PDCardResetSocket
PDCardGetSocket | PDCardSetAdapter
PDCardGetWindow | PDCardSetSocket
PDCardInquireAdapter | PDCardSetWindow
PDCardInquireWindow | PDCardWriteAttrByte
PDCardReadAttrByte | PDCardWriteCmnByte
PDCardReadCmnByte |


Sample Serial Port Driver

The serial port driver handles any I/O devices that behave like serial ports, including those based on 16450 and 16550 universal asynchronous receiver-transmitter (UART) chips and those that use direct memory access (DMA). Many Windows CE–based platforms have devices of this type, including ordinary nine-pin serial ports, infrared I/O ports, and PC Card serial devices, such as modems. If multiple types of serial port exist on a platform, you can either create several different serial drivers, one per serial port type, or create several different PDD layers and link them to a single MDD, thus creating one multipurpose serial driver. Either approach is equally acceptable. Creating separate drivers can simplify debugging and maintenance because each driver supports only one type of port. Creating a multipurpose driver, such as the sample serial port driver for the Windows CE reference platform, is more complex but gives a small memory savings.

The sample serial port MDD driver code appears under Public\Common\Oak\Drivers\Serial. The PDD code for various platforms is in Platform\CEPC\Drivers\Ser_Pdd and Platform\Odo\Drivers\Serial. There are sample serial port PDDs that support standard 16550, PC Card–based, and infrared serial ports. The sample MDD also supports linking multiple PDD layers, as described previously, by using a function pointer array that defines the types of supported serial port. If you add serial devices with unusual properties or functionality, you can add new serial port PDDs. In addition, Microsoft provides a library of functions appropriate for supporting serial ports that use 16550-compatible UARTs under Public\Common\Oak\Drivers\Ser16550. The COM_Open function in the serial port MDD does not support the fErrorChar, fNull, and fAbortOnChar members of the serial device control block (DCB) structure. You are expected to add support for this functionality in your PDD layer, if appropriate for your serial port hardware.

Because the functionality of serial ports maps easily to the functionality provided by standard stream interface functions, the serial port driver uses the stream interface functions as its DDI. Like other drivers that expose stream interface functions, it is loaded by the Device Manager.

Serial port devices make extensive use of I/O control codes to set and query various attributes of a serial port. For example, there are I/O control codes for setting and clearing the Data Terminal Ready (DTR) line, for purging any undelivered data, and for getting the status of a modem device. Therefore, you should support as many IOCTL_SERIAL I/O control codes as possible in your implementation of COM_IOControl.

The following table shows the DDI functions for the serial port driver.

COM_Close | COM_PowerDown
COM_Deinit | COM_PowerUp
COM_INIT | COM_Read
COM_IOControl | COM_Write
COM_Open |

The following table shows the DDSI functions for the sample serial port driver.

GetSerialObject | HWGetIntrType | HWPutBytes
HWClearBreak | HWGetModemStatus | HWReset
HWClearDTR | HWGetRxBufferSize | HWSetBreak
HWClearRTS | HWGetRxStart | HWSetCommTimeouts
HWClose | HWGetStatus | HWSetDCB
HWDeinit | HWInit | HWSetDTR
HWDisableIR | HWOpen | HWSetRTS
HWEnableIR | HWPowerOff | HWTxIntrHandler
HWGetBytes | HWPowerOn | HWXmitComChar
HWGetCommProperties | HWPurgeComm |

These function names are listed as they are defined in the sample serial port code. You can change this set of functions or the function names by modifying the serial object table, which is a table of HWOBJ type objects, in the serial port PDD.


Power Management in Serial Port Drivers

The minimum of power management that a serial port driver can perform is to put the serial port hardware into its lowest power consumption state with the driver’s HWPowerOff function, and to turn the serial port hardware fully back on with the driver’s HWPowerOn function. Both of these functions are implemented in the serial port driver’s PDD layer. Beyond that minimal processing, a serial port driver can conserve power more effectively by keeping the port powered down unless an application has opened the serial port. Most serial port hardware can support reading the port’s input lines even without supplying power to the serial. Consult the documentation for your serial port hardware to determine what parts of the serial port circuitry can be selectively powered on and off, and what parts need to be powered for various conditions of use. If there is no need for the driver to detect docking events for removeable serial port devices, the driver can go one step further and remove power from the serial port’s UART chip, provided no applications are using the port.


Automatic Detection of Docking for Serial Ports

To support automatic detection of docking events for removeable serial port hardware, serial port drivers can monitor the Data Carrier Detected (DCD) line. For any serial port which is subject to automatic detection, such as PC Card–based serial port hardware, the driver can use the CeEventHasOccured function to watch for the NOTIFICATION_EVENT_RS232_DETECTED message. When such a message occurs, the user has docked a serial port. Some Windows CE–based platforms that support Direct Cable Connect synchronization services starts the synchronization services when this event occurs. See Platform\Odo\Drivers\Serial\p2io.c for an example of detecting this message.


Sample Touch Screen Driver

The touch screen driver reads input from the touch screen hardware and converts it to touch events that are fed into the input system. The driver is also responsible for converting uncalibrated coordinates to calibrated coordinates that take into account any hardware anomalies, such as skew or nonlinearity. This calibration is generally done when the driver is first loaded, after a cold startup of a Windows CE–based platform. The sample code appears under \Platform\ODO\Drivers\Touchp.

The driver must submit points while the stylus is touching the touch screen. When the stylus is removed from the touch screen, the driver must submit at least one final event indicating that the stylus tip was removed. The calibrated coordinates must be reported to the nearest one-fourth pixel.

The following pseudocode example shows the calibration algorithm.

TouchPanelEnable(...);  // Start the panel sampling.
TouchPanelGetDeviceCaps(...); // Request number of calibration points.
for (i=0; i<# points; i++)
  {
    TouchPanelGetDeviceCaps(...); // Get a calibration coordinate.
    //Draw crosshair at returned coordinate.
    TouchPanelReadCalibrationPoint(...); // Get calibration data.
  }
TouchPanelSetCalibration(...); // Calculate calibration coefficients.

After calibration, the touch screen driver sends any pen samples generated for the touch screen to the callback function specified in the TouchPanelEnable function. The driver must pass calibrated points to the callback function.

The following table shows the DDI functions for the touch screen driver.

ErrorAnalysis | TouchPanelPowerHandler
TouchPanelCalibrateAPoint | TouchPanelReadCalibrationAbort
TouchPanelDisable | TouchPanelReadCalibrationPoint
TouchPanelEnable | TouchPanelSetCalibration
TouchPanelGetDeviceCaps | TouchPanelSetMode

The following table shows the DDSI functions for the touch screen driver.

DdsiTouchPanelDisable
DdsiTouchPanelEnable
DdsiTouchPanelGetDeviceCaps
DdsiTouchPanelGetPoint
DdsiTouchPanelPowerHandler
TouchDriverCalibrationPointGet
DdsiTouchPanelSetMode


Sample USB Host Controller Driver

This section describes the specific aspects of universal serial bus (USB) support in Windows CE 2.10 and later that are relevant to OEMs who want to add USB support to their Windows CE–based platforms. For a complete overview of USB support in Windows CE, including information directed to IHVs, see Universal Serial Bus Drivers.

The primary goal of Windows CE USB support, aside from enabling IHVs to write device drivers for USB devices, is to help OEMs expand existing USB support on their platforms. Currently, USB support includes only the host side of the USB specification, which enables Windows CE to support USB peripherals. OEMs are free to add device-side support if their Windows CE–based platforms need to act as USB peripherals to other USB hosts.


OHC and UHC Host Controllers

The host controller, or adapter, is a hardware layer contained within the host computer: in this case, a Windows CE–based platform. The host controller converts data between the format used by the host computer and the format used on the bus. There are two standard host-controller designs, open host controller (OHC) and universal host controller (UHC). OEMs are responsible for providing driver software for the particular host controller hardware present on their Windows CE–based platforms. Microsoft supplies a sample host controller driver that an OEM can use as a basis for a host controller driver (HCD). For more information about USB host controllers, see Writing an HCD Module.


HCD Nested Hub Support

Windows CE guarantees support for connecting hub devices only up to one level deep. In laboratory settings, the HCD module supplied by Microsoft has supported several layers of nested hubs; however, this feature could not be thoroughly tested and certified before the release of Windows CE 2.10. OEMs who want to support multiple layers of nested hubs are strongly encouraged to test the behavior and power consumption of peripherals thoroughly under a wide variety of hub configurations before announcing support for multiple levels of hubs in their products.


Suspending and Resuming

Windows CE supports suspending and resuming USB devices in association with the standard Windows CE power states. When Windows CE issues a POWER_DOWN notification, the HCD module suspends the USB host controller hardware and all devices. To achieve this, the MDD layer of the HCD module calls a function in the PDD layer to enable the HCD module to complete any platform-specific processing needed to suspend the host controller hardware properly. Suspending power to the host controller hardware typically causes USB devices connected to a Windows CE–based platform to enter the suspended state. However, this is not recommended for all devices; USB devices that can collect and store data while the host computer is off should not be suspended.

When the Windows CE–based platform is turned on again, Windows CE sends a POWER_UP notification to the HCD module. Next, the MDD layer of the HCD module calls a function in the PDD layer. Because the PDD layer is used, OEMs can customize the HCD module to perform any necessary platform-specific processing. Following the call to the PDD layer, the HCD module re-initializes the host controller hardware.

When the host controller hardware has been re-initialized, the USB driver module unloads the USB device drivers loaded prior to the POWER_DOWN notification, identifies all the USB devices currently connected to the bus—a process called bus enumeration—and loads the USB device drivers for those devices. This suspend and resume processing is very similar to that performed by the Windows CE Device Manager for PC Card–based devices.


Bus-powered and Self-powered USB Devices

Windows CE 2.10 provides full support for bus-powered and self-powered USB devices. When a user connects a self-powered or bus-powered device to a Windows CE–based platform, the USB system software automatically accepts or rejects the device, based on the power requirements of the device. The power model is the same for both bus-powered and self-powered devices.

When a USB device is attached to a Windows CE–based platform, the HCD module sets the initial power configuration. During the device attachment processing phase, the HCD module reads the power requirements of the USB device configurations from the device configuration descriptor structures. In this way, the HCD module can choose an appropriate power configuration for the device.

Some devices may provide several configurations with different power requirements. OEMs who port an HCD module to their hardware can implement policies to choose the appropriate power configurations from those provided by the USB devices.

For example, Windows CE–based platforms have a registry setting that specifies the maximum total current draw allowable for USB devices connected to the host computer. If enabling a device would exceed this power threshold, the device is not configured unless the device has an alternate configuration with acceptable power requirements. OEMs can customize the platform-specific portions of the HCD module to choose dynamically whether to configure devices based on the current system power level. OEMs can implement a power model suitable for their platforms because the HCD module calls platform-specific code in its PDD layer for all USB devices connected to the bus. Therefore, an OEM can implement a power model that can selectively grant or deny power to individual USB devices according to whatever criteria the OEM chooses.

Because an HCD module cannot know which configuration might be appropriate for different uses of a USB device, a USB device driver can change its device configuration after the device driver is loaded, to the extent that the new configuration meets overall system power requirements. A USB device driver uses the SetConfiguration function to change a USB device configuration. In the unconfigured state, USB devices may not draw more than 100 mA.


USB Components Supplied by Microsoft

Microsoft supplies the following USB software components:

  • The USB driver module, which loads USB device drivers and manages resources in the USB subsystem.
  • The complete set of USB driver interface functions listed in the Universal Serial Bus Specification, Revision 1.0 and implemented by the USB driver module. The API includes transfer functions, pipe functions, device configuration functions, and miscellaneous functions. This API enables developers to write USB device drivers to support any USB-compliant devices.
  • A sample HCD module that works with open host controller driver (OHCD)–compliant USB host controllers. OEMs must port this module to their hardware in order to support USB on their Windows CE–based platforms.
  • A sample USB mouse device driver, which is loaded by the USB driver module. The sample driver works with most generic USB mouse devices. Microsoft provides the sample for OEMs and IHVs to use solely as a reference while developing USB device drivers for their own USB devices.

Source code for these components is available in \Wince\Public\Common\Oak\Drivers\USB located in the Platform Builder. Header files are in \Wince\Public\Oak\Inc and \Wince\Public\Ddk\Inc. Platform sample code is in Platform\Cepc\Drivers\Usb.


Writing an HCD Module

To support USB on a Windows CE–based platform, OEMs must customize the HCD module included with the Platform Builder. Microsoft provides a sample HCD module that works with OHCD-compliant USB host controllers. The sample OHCD is designed for a Windows CE–based platform. OEMs must port the sample OHCD to their platforms as part of their OAL implementations.

To ease the porting effort, the OHCD is divided into two parts: a platform-independent MDD and a small PDD. This is similar to the MDD/PDD device driver model used by Windows CE–based native device drivers. As with the native device driver model, OEMs need to port only the PDD part. Furthermore, because the specifications for OHC interface and UHC interface hardware explicitly define the behavior of such hardware, the PDD layer does very little. The PDD layer for most HCD modules merely has to locate the hardware address of the host controller within memory and provide the MDD layer with the hardware address and a pointer to a shared memory area.

However, the MDD and PDD layers in the HCD module interact more than the MDD and PDD layers in most native device drivers. For example, in the majority of native device drivers, the MDD layer calls DDSI functions exposed by the PDD layer. In the HCD module, the MDD layer not only calls the DDSI functions, but also exposes a set of functions that the PDD layer must call at specific times during initialization.

OEMs must create a registry key within HKEY_LOCAL_MACHINE\Drivers\Builtin\ so that the Device Manager loads the HCD module when the platform starts. Device drivers that the Device Manager loads must expose some of the stream interface functions. Therefore, the PDD layer is required to include some additional DDSI functions, such as OhcdPdd_Open and OhcdPdd_IoControl, even though the HCD module is not a stream interface driver. The benefit of this approach is that the Device Manager calls the HCD module’s OhcdPdd_Init function, which in turn enables the HCD module to call the required MDD functions. The following example shows the registry key for the HCD module; it should contain the same values as other stream interface driver keys.

[HKEY_LOCAL_MACHINE\Drivers\Builtin\OHCI]
  “Prefix”=“HCD”
  “Dll”=“ohci.dll”
  “Index”=dword:1
  “Order”=dword:1

The following table shows the MDD functions that the PDD layer must call.

OhcdMdd_CreateMemoryObject
OhcdMdd_DestroyMemoryObject
OhcdMdd_CreateOhcdObject
OhcdMdd_DestroyOhcdObject
OhcdMdd_PowerUp
OhcdMdd_PowerDown

The following table shows the DDSI functions exposed by the PDD layer.

OhcdPdd_CheckConfigPower | OhcdPdd_Open
OhcdPdd_Close | OhcdPdd_PowerDown
OhcdPdd_Deinit | OhcdPdd_PowerUp
OhcdPdd_DllMain | OhcdPdd_Read
OhcdPdd_Init | OhcdPdd_Seek
OhcdPdd_IoControl | OhcdPdd_Write

OEMs must write their own HCD modules if their platforms contain universal host controller driver (UHCD)–compliant host controllers, instead of OHCD-compliant host controllers. An HCD module for UHCD hardware must expose the same interface to the USB driver module as the sample HCD module. The OHCD sample is suitable to use as a model while developing an HCD module for UHCD hardware.


Adding Drivers for Additional Built-In Devices

You can add hardware devices to your Windows CE–based target platform that are not directly supported by Windows CE. However, if you do, you must supply device drivers for the additional devices.

Windows CE currently supports several classes of device through the GWES module. OEMs cannot add new device classes through this module because this would require adding code to the module to enable it to handle I/O events for the new device classes. The Platform Builder does not include source code for the GWES module, which means that only Microsoft can add support for new device classes through the module.

Because the GWES module is not extensible, OEMs must provide drivers for any new types of device by using the other Windows CE–based driver model, the stream interface driver model. Stream interface drivers are user-mode DLLs managed by the Device Manager. Unlike native device drivers, each of which has its own interface to the GWES module, all stream interface drivers expose the same basic interface to the kernel. This interface consists of a set of functions that presents the capabilities of a device in terms of standard file I/O functions.

Windows CE versions 1.01 and later provide kernel support to enable stream interface drivers to access additional built-in hardware devices. Stream interface drivers can call the KernelIOControl function, which provides a generic method for OEMs to expose new functionality on their Windows CE–based platforms. KernelIOControl passes its parameters to the OEMIoControl function in the OAL, which OEMs can use to provide whatever hardware access is necessary. The Platform Builder has complete documentation on KernelIOControl and on the OAL.

For more information, see Writing a Stream Interface Driver DLL.


Developing Stream Interface Device Drivers

Stream interface drivers are dynamic-link libraries (DLLs) that typically are loaded, controlled, and unloaded by a special application called the Device Manager. In contrast to native device drivers, which have special single-purpose interfaces, stream interface drivers all use the same interface and expose a common set of functions, the stream interface functions.

Stream interface drivers are designed for peripheral devices connected to a Windows CE–based platform. Examples of these devices are modems, printers, digital cameras, and PC Cards. All peripheral devices must be attached through external connectors, such as serial ports or PC Card sockets. Therefore, device drivers for peripheral devices are like printer drivers for desktop computers: both run as user-mode processes that access the services of built-in hardware to control their devices. Device drivers for serial devices use the serial port. Device drivers for PC Cards use the PC Card Services library; in turn, the PC Card Services library controls the PC Card socket hardware. Because of these interdependencies, a stream interface driver often uses a native device driver—specifically, the native device driver for the external connector to which the peripheral is attached—in order to interact with the peripheral. However, stream interface drivers can interact directly with a peripheral if that peripheral is mapped to some portion of the system’s memory space, as do stream interface drivers for devices that are often built into a Windows CE–based system, such as speakers and microphones.

The primary task of a stream interface driver is to expose the services of a peripheral to applications by presenting the device as a special file in the file system. This is similar to other operating systems, such as UNIX, which exposes peripheral devices by means of special files in the file system \Dev directory. Although Windows CE does not have a direct analog to the UNIX \Dev directory, the device files in Windows CE are stored in the \Windows directory, and a special naming convention differentiates the device files from ordinary files.

Despite the generic characteristics of stream interface drivers, they can be implemented in different ways. For example, even though stream interface drivers typically are designed by independent hardware vendors (IHVs) for peripheral devices, OEMs who customize Windows CE–based platforms sometimes write stream interface drivers for certain built-in devices. In addition, although stream interface drivers are usually loaded and unloaded by the Device Manager, sometimes applications perform the loading and unloading.

Application-specific stream interface drivers present resources in ways that an application can readily use. Peripheral devices are the most common resource used by application-specific stream interface drivers, but almost any resource, such as memory, process lists, or TCP/IP ports, can be presented in terms of a stream interface driver. For example, a company that makes Global Positioning System (GPS) receivers could make two versions of the receiver: one that is built into a PC Card and one that connects to an external serial port. Rather than adding complexity to the application that uses the GPS receiver so that the application can use either type of receiver, the company could write a device driver that repackages the services of one type of receiver in the interface of the other type. Thus, the application would not need to distinguish between the two types of receiver connected to the platform; both types would react identically to the application despite the different access methods used for serial and PC Card devices.

The following sections describe how to write stream interface drivers in greater detail. Included are explanations of the system architecture for stream interface drivers, device file names, the Device Manager, entry points, and the relationship of a stream interface driver to a device and to applications.


System Architecture for Stream Interface Drivers

A stream interface driver receives commands from the Device Manager and from applications by means of file system calls. The driver encapsulates all the information necessary to translate those commands into appropriate actions on the devices it controls.

The following illustration shows the relationship between a stream interface driver and other system components.

The following definitions apply throughout the Windows CE Device Driver Kit:

User application
A user application includes any application that accesses a peripheral device. Access to a peripheral is through the file system and the special files that expose the services of peripherals.
Kernel
The kernel, the core of the Windows CE operating system, provides basic services to the application. To support stream interface drivers, the kernel redirects the file I/O function calls of the application to the appropriate entry points in the stream interface driver.
Device Manager
The Device Manager is a special application that loads and unloads stream interface drivers. For more information, see Device Manager.
Stream interface driver
A stream interface driver is a DLL that manages a peripheral device. It exposes file I/O functions to applications and implements those functions by accessing its peripheral device to map the device’s capabilities to the semantics of the file I/O functions. Stream interface drivers can either use an underlying native device driver to access the physical peripheral devices that the driver serves or access its device directly if the device is mapped into memory. Audio device drivers for built-in audio hardware are an example of direct access.
Native device driver
A native device driver is a device driver supplied by the manufacturer of a Windows CE–based platform. Some stream interface drivers use native device drivers to access peripherals because peripherals are attached to platforms through connectors managed by native device drivers. The native device drivers used by stream interface drivers are generally drivers for various sorts of I/O ports, such as serial ports or PC Card sockets.
Windows CE–based platform
A Windows CE–based platform consists of a CPU, memory, clock, and possibly other hardware, such as a keyboard and touch screen. Stream interface drivers generally use the I/O ports on a platform, whereas the kernel can use all of a platform’s hardware.
Peripheral device
A device—such as a modem, printer, microphone, keyboard, touch screen, and so on—that is managed by a device driver.


Device Manager

This section discusses the Device Manager, its position within the Windows CE operating system, and its management of stream interface drivers. Developers do not need in-depth knowledge of the Device Manager to write stream interface drivers, but a broad understanding of the Device Manager and its role within Windows CE is useful.

The Device Manager, a user-level process, typically runs continuously on a Windows CE–based platform. The Device Manager is not part of the kernel, but is a separate application that interacts with the kernel, with the registry, and with stream interface driver DLLs. More specifically, the Device Manager performs the following tasks:

  • Initiating the loading of a driver at system startup or when it receives notification that a user has attached a peripheral to the platform. For example, when a user inserts a PC Card, the Device Manager attempts to locate and load a device driver for that PC Card.
  • Registering special file names with the kernel that map the stream I/O functions used by applications to the implementations of those functions within a stream interface driver.
  • Finding the appropriate device driver for a peripheral by obtaining a Plug and Play identifier from the peripheral device or by invoking a detection routine to find a driver that can handle the device.
  • Loading and tracking drivers by reading and writing registry values.
  • Unloading drivers when their devices are no longer needed. For example, the Device Manager unloads a PC Card device driver when a user removes the card.


Registry Keys Used by the Device Manager

The Device Manager uses registry keys stored in the HKEY_LOCAL_MACHINE\Drivers\ key. The following are the major subkeys of the HKEY_LOCAL_MACHINE\Drivers\ key:

Active\
The Active\ key contains subkeys that track currently active drivers loaded by the Device Manager. Device driver setup routines should not modify the Active\ key’s contents, nor should they rely on the presence of any specific values within the Active\ key.

When a device driver is loaded, the Device Manager passes it the path to its Active\ key as the dwContext parameter in the device driver’s XXX_Init function. The device driver can rely on the presence of the following values:

  • Hnd

    Device handle from the RegisterDevice function

  • Name

    Device file name

  • Key

    Registry path within HKEY_LOCAL_MACHINE to the device driver key

The Active\ key for PC Card device drivers has the following additional values:

  • PnpId

    Plug and Play identifier string

  • Sckt

    Current socket and function pair of the PC Card

Once a device driver is loaded, it can add values to its Active\ key. However, the Device Manager deletes the device driver Active\ key and any values in it when the device driver is unloaded.

Builtin\
The Builtin\ key contains subkeys that govern stream interface driver DLLs provided by the manufacturer of a Windows CE–based platform. As stated, OEMs can implement drivers for certain types of built-in devices, using the stream interface driver model.
PCMCIA\
The PCMCIA\ key contains subkeys related to PC Cards and their stream interface drivers. The most important information in these subkeys is the Plug and Play identifier of the PC Card, which corresponds to a specified driver.
Detect\
The Detect\ subkey contains numbered entries that list DLL names and detection functions. The functions identify a generic stream interface driver for PC Cards with no Plug and Play identifier or PC Cards with an unknown Plug and Play identifier. For more information, see Drivers\PCMCIA\Detect.
Driver
Driver subkeys, named after generic PC Card drivers, contain values used to load the drivers. The Device Manager creates individual Driver subkeys when a generic stream interface driver detection function indicates that it can drive a particular device. The existence of a Driver subkey indicates detection by a driver that has an entry within the PCMCIA\Detect\ key.
Plug-and-Play ID
Plug-and-Play ID subkeys contain values used to load stream interface drivers for PC Cards. Typically, the setup routine for a PC Card driver creates these subkeys when the driver is installed on a platform.


Loading Stream Interface Drivers

There are three ways of loading stream interface drivers. Two of them involve the Device Manager, but the third is specific to applications.

The first type of loading occurs at startup. When a Windows CE–based platform starts up, it starts the Device Manager. In turn, the Device Manager reads the contents of the HKEY_LOCAL_MACHINE\Drivers\Builtin registry key and loads any stream interface drivers listed there. For example, on many Windows CE–based platforms the Device Manager loads the driver for built-in serial ports (Serial.dll) through this mechanism.

The second type of loading occurs when the Device Manager automatically detects the connection of a peripheral device to a platform. A PC Card is the most common type of automatically detectable device because the PC Card socket controller notifies Windows CE when a user inserts a PC Card. When a user inserts a PC Card into a socket, the Device Manager calls the socket driver, which is a native device driver, to find the Plug and Play identifier. The Device Manager then checks the HKEY_LOCAL_MACHINE\Drivers\PCMCIA\ key for a subkey matching the Plug and Play identifier. If one exists, it loads the driver listed within that key. If there is no match, the Device Manager calls all the detection functions listed within the HKEY_LOCAL_MACHINE\Drivers\PCMCIA\Detect key. If one of the detection functions returns a value indicating that it can handle the PC Card, the Device Manager loads and initializes that stream interface driver.

In the first and second types of loading, the Device Manager calls the RegisterDevice function for the stream interface driver and creates a numbered subkey within the HKEY_LOCAL_MACHINE\Drivers\Active\ key to track the driver. RegisterDevice also locks the stream interface driver into working RAM. This prevents the driver from being swapped out and prevents any paging activity that would slow driver operation when servicing interrupts.

The third type of loading occurs when the Device Manager cannot automatically detect the connection of a peripheral to a platform. Unrecognized devices are often serial devices because there is no automatic way for Windows CE to detect the connection of a serial device to a serial port. If the Device Manager cannot automatically recognize a peripheral, the application that needs to use the peripheral must load the peripheral’s driver. The following is the standard sequence of actions for this type of loading:

  1. A user starts the application.
  2. The application determines that the device driver is not loaded, either by inspecting the file system or by receiving a failure return value from the CreateFile function when it tries to open the device file name of the peripheral. For more information, see Device File Names.
  3. The application calls RegisterDevice to load the stream interface driver and lock it into memory.
  4. The application continues with its usual operation.


Unloading Stream Interface Drivers

A stream interface driver DLL can be unloaded in two ways, depending on the method by which the DLL was loaded. If the Device Manager loaded the DLL, the Device Manager detects the disconnection of the stream interface driver’s peripheral from the platform, such as when a PC Card is ejected from its socket. At this point, the Device Manager removes the driver’s entry from the HKEY_LOCAL_MACHINE\Drivers\Active key, calls the DeregisterDevice function to remove the peripheral’s device file name from the file system, and notifies the FreeLibrary function to unload the DLL. However, if an application loaded the DLL, the application must unload the DLL before it exits by calling DeregisterDevice.


Device File Names

As mentioned, applications access peripheral devices through special entries in the file system. The file system code in the Windows CE operating system includes code that recognizes these special file names and redirects file I/O operations to the appropriate stream interface driver.

This section on device file names provides information about the file name formats, prefixes, and indexes you need to establish to develop stream interface drivers. For more information on how to use device file names when developing a stream interface driver, see Writing a Stream Interface Driver DLL.


Device File Name Format

The file system recognizes file names as special device files if the file names consist of exactly three uppercase letters, a single digit, and a colon (:). This format follows the convention established in the Microsoft® MS-DOS® operating system for serial and parallel ports. For example, “COM1:”, “PGR7:”, and “GPS0:” are valid device file names, but “MODEM1:”, “COM27:”, and “LPT1” are not.


Device File Name Prefixes

The prefix consists of three uppercase letters that identify which special device file name corresponds to a particular stream interface driver. The prefix is stored in a registry value called Prefix, which is located within the key for the driver. Typically, the setup utility that installs a driver creates this registry value along with the other values that stream interface drivers need.

When you create a stream interface driver, you designate the three-letter prefix. It can be any three letters, although you should use a common prefix if your driver is for the same class of device as other drivers already present on the platform. For example, drivers for serial devices such as modems could use the common prefix COM, even though other drivers might already be using that prefix. Your driver can distinguish itself from any others with the same prefix by using a different index. For more information, see Device File Name Indexes.

Windows CE uses the prefix in two important ways. First, the prefix identifies all possible device file names that can access the stream interface driver. Second, the prefix tells the operating system what entry-point names to expect in the stream interface driver DLL. For example, to implement a device driver for a PC Card pager, you could choose PGR as the three-letter prefix, which in turn would dictate entry-point names, such as PGR_Open, PGR_IOControl, and so on.


Device File Name Indexes

In a special device file name, the index is the digit that follows the prefix. The index differentiates devices managed by a stream interface driver. By default, the Device Manager numbers indexes logically from 1 through 9, with 1 corresponding to the first device file name. If you require a tenth device file name, use 0 as the index.

If you need to number your device file names starting at an index other than 1, specify a starting index in a registry value called Index within the registry key for your driver. This is often necessary if your stream interface driver serves a device that should use a common prefix, such as COM. For example, on many Windows CE–based platforms, “COM1:”, “COM2:”, and “COM3:” correspond to built-in serial port hardware. If your driver is for a serial device, such as a packet-radio modem, it should appear as a COM port because modem software often assumes that modems are connected to COM ports. You could specify an Index value of 4 to differentiate your serial device from the ones built into the hardware.

If you specify an index, rather than letting the Device Manager assign indexes as needed, by default your driver supports only one device because the Device Manager can register only one device file name. If you need to specify an index but need more than one device file name, you have two options: the XXX_Init function can register additional device file names with the RegisterDevice function, or the setup utility can create additional sets of registry keys, each with a different index, when your driver is installed.


Writing a Stream Interface Driver DLL

The following sections explain the important issues that affect your design decisions as you implement a stream interface driver DLL. Topics covered include how to create a DLL containing required entry points for stream interface drivers, how to regulate either single access or multiple access to a driver, and, for developers who implement interrupt-driven devices, how to plan for interrupt processing and real-time processing. In addition, this section offers specific information regarding drivers for serial devices and PC Card devices. The final section discusses the installation of a stream interface driver on a Windows CE–based platform.


Required Entry Points for Stream Interface Driver DLLs

For every stream interface driver DLL, the required entry points implement standard file I/O functions plus power management functions used by the Windows CE kernel. The following table shows the required entry points.

XXX_Close | XXX_Deinit
XXX_Init | XXX_IOControl
XXX_Open | XXX_PowerDown
XXX_PowerUp | XXX_Read
XXX_Seek | XXX_Write

When you create a DLL, replace XXX in the entry-point names with a device file name prefix. For more information, see Device File Name Prefixes.


Single Access and Multiple Access

Because peripheral devices are exposed to applications as special files when you create a stream interface driver, you provide the implementation of such a file. Therefore, consider whether it is practical, based on the capabilities of the device that your driver serves, to enable multiple applications to have simultaneous access to the special file; that is, consider whether your driver can have multiple open file handles on its device. A stream interface driver can implement either single access or multiple access by using the hOpenContext parameter that Windows CE passes to all file I/O functions.

To enable multiple access, each call to the XXX_Open function should return a different value for hOpenContext. The device driver must track which return values from XXX_Open are in use. Subsequent calls by Windows CE to XXX_Close, XXX_Read, XXX_Write, XXX_Seek, and XXX_IOControl pass these values back to the device driver, enabling the driver to identify which internal data structures to manipulate.

To enforce single access, only the first call to XXX_Open should return a valid hOpenContext value. As long as this value remains valid, which is until Windows CE calls XXX_Close for the value, subsequent calls to XXX_Open should return NULL to the calling application to indicate failure.


Interrupt Processing

Some peripheral devices can cause or signal interrupts on the bus of a Windows CE–based platform. Typically, the peripherals are PC Cards. Some Windows CE–based platforms use standard buses, such as the Peripheral Component Interconnect (PCI) local bus, in which case, expansion cards plugged into the bus can also signal interrupts. Because these peripheral devices can cause or signal interrupts, their stream interface drivers need code to process interrupts.

The recommended method for processing interrupts is for the stream interface driver to spawn a new thread called an interrupt service thread (IST) during its processing of the XXX_Init call. When an interrupt occurs, Windows CE signals the IST. The IST interacts with the peripheral device to perform whatever device-specific processing is necessary to handle the interrupt. This method is beneficial because Windows CE versions 2.12 and earlier do not support nested interrupts. Thus, while an interrupt service routine (ISR) is running, other interrupts are masked for a short time. ISRs should therefore do as little processing as possible, only report the logical interrupt value to the operating system so that Windows CE can activate the corresponding IST. By separating the interrupt processing into a very short ISR and a longer user mode IST, interrupts can be masked for as little time as possible.

ISTs generally run at a high priority so that they can respond quickly to interrupt events. For most drivers, this thread should register to receive interrupt notifications from the InterruptInitialize function. For PC Card drivers, however, the thread receives notifications from the CardRequestIRQ function. PC Card drivers do not process interrupts directly because the built-in PC Card socket driver gets the raw interrupts generated by the PC Card socket. CardRequestIRQ allows you to specify a callback function that the PC Card socket driver calls when an interrupt occurs.


Real-Time Processing

Hard real-time processing performance of Windows CE versions 2.12 and earlier varies widely according to processor and bus speed. As mentioned, Windows CE versions 2.12 and earlier do not support nested interrupts, which greatly limits real-time processing. On the Windows CE–based reference platform, which uses the Hitachi SH3 microprocessor, interrupt-driven device drivers are typically started within 90 to 170 microseconds after the interrupt occurs, yielding theoretical sampling rates of about 5.8 to 11 kHz. The variability is due to unpredictable factors, such as what data is currently in the processor cache and whether the device driver process happens to be the one currently executing. On other hardware, factors such as CPU speed, bus speed, and the speed of the manufacturer’s interrupt vectoring routines determine the lower limits of interrupt latency. Because the ISTs of device drivers can be pre-empted by high-priority threads, there is no absolute upper limit. In general, however, the latency for servicing interrupts in Windows CE is less than the latency for Windows-based desktop platforms; device drivers are unlikely to lose data unless they are starved for processor time by other high-priority threads running on the system. Device drivers for polled devices may be able to achieve higher sampling rates, because polled devices do not generate interrupts and are therefore not subject to the same latencies.

Peripherals that connect to Windows CE through a serial port can do so at the maximum speed of the serial port. Most serial ports are buffered internally by 16550-class universal asynchronous receiver-transmitters (UARTs) capable of relaying 115 kilobits per second; consult the manufacturer for specific information. PC Card socket speeds vary also; again, the authoritative source of information is the manufacturer.

To reduce the time that it takes your stream interface driver to handle incoming data, defer complicated processing. If the device driver restricts itself to collecting the data in memory, it can leave processing of that data for later, to be handled by a low-priority thread or user-level application.


Drivers for Serial Devices

Windows CE supports two methods of driving serial devices. The first requires you to create a stream interface driver DLL that presents high-level information from the device to applications. The second does not require you to write a driver; instead, it requires the applications that use the device to interpret the device data.

These two methods are possible because serial devices are always accessed through built-in COM ports, generally “COM1:” through “COM3:”. With the first method, you implement a serial device driver to present a new device file name to applications, such as “COM4:” or another file name specific to the function of the serial device. Internally, a device driver uses the services of the built-in COM port to access the peripheral. You can also let user applications open a built-in COM port to access the peripheral device directly.

The following are the factors allowing you to decide between these two strategies:

  • Single access or multiple access

    If the peripheral can support simultaneous access by multiple applications, implement a stream interface driver. This greatly simplifies the user-level applications. For more information, see Single Access and Multiple Access.

  • Complexity of the incoming data stream

    If the incoming data stream from the peripheral is complicated and requires considerable processing to yield usable information, you probably should write a stream interface driver.

  • Speed of the incoming data stream

    If data comes from the peripheral at a very high rate, there might not be enough processing time available to support the overhead required for a stream interface driver. In this case, you might have no choice but to put all processing into the user-level application.


Drivers for PC Card Devices

Stream interface drivers for PC Cards are more complex than drivers for serial devices because PC Cards themselves tend to be more complex. As described in System Architecture for Stream Interface Drivers, stream interface drivers access peripheral devices through built-in hardware. For PC Cards, the built-in hardware is the PC Card socket or sockets available on a Windows CE–based platform. Specifically, these sockets are PC Card Type II sockets. The sockets are driven by the built-in PC Card socket driver, which implements the socket functions that you use to write stream interface drivers for PC Cards.

Most PC Card socket functions have a parameter that represents a socket and function pair. A socket and function pair is a combination of one particular PC Card socket and one particular function of a PC Card. Socket and function pairs support multifunction PC Cards and platforms with more than one PC Card socket. Drivers for multifunction cards should register one device file name for each function. Any drivers that you create for PC Cards should also be written to work with any PC Card socket because different platforms have different numbers of sockets.

If you write a generic PC Card driver—one that can drive an entire class of PC Cards adhering to a specified operating standard—you need an additional entry point in the DLL for a detection function. The Device Manager uses the detection function when a user inserts an unknown PC Card with no Plug and Play identifier. This function must conform to the PFN_DETECT_ENTRY prototype declared in Public\Common\DDK\Inc\DevLoad.h. For more information on PC Card detection functions, see Device Manager and Drivers\PCMCIA\Detect.


Installing a Stream Interface Driver DLL

Installing a stream interface driver DLL on a Windows CE–based platform is a relatively simple procedure. However, you should provide a setup application for users because proper installation of most stream interface drivers requires changes to the registry. The setup application runs on a host computer and connects to a platform through a serial cable or similar connection.

The setup application must perform the following steps:

  1. Connect to the Windows CE–based platform or detect that a connection already exists.
  2. Copy the stream interface driver DLL into the \Windows directory of the platform.
  3. Create registry keys and values for the driver, if necessary.

For information about connecting a host computer to a platform and copying files from a host computer to a platform, see the Windows CE Platform SDK. For information about required registry keys for a stream interface driver, consult the Reference included in this documentation.


Sample Stream Interface Drivers

The Platform Builder contains sample device drivers that illustrate how to write stream interface drivers for several types of device. If you implement a stream interface driver for a device similar to one of the samples, you can base your driver on the appropriate source code of the sample driver. The following table shows the sample device drivers contained in the Platform Builder.

Sample
Description
Pager Card | Illustrates a device driver for the Motorola NewsCard pager
Modem Card | Illustrates a device driver for a PC Card modem
RAM Card | Illustrates a device driver for a Static RAM PC Card
PC Card Test | Illustrates a device driver for testing PC Cards
Serial | Illustrates a device driver for devices that connect to a serial port
Touch Screen | Illustrates a device driver that interacts with the screen

The following are PC Card drivers:

  • 16550mod

    A sample client driver for an I/O-type PC Card. A sample application included with this driver opens, writes, reads, and closes a device by making calls to the 16550MOD driver.

  • Pager

    A sample pager PC Card driver supporting the Motorola NewsCard pager. The Platform Builder includes a sample application that enables users to receive and view pages.

  • Ramcard

    A sample driver for a memory-type PC Card. The Platform Builder includes two sample applications for writing to and reading from the card.

  • Cardtest

    A sample driver and test for a block of memory on a PC Card memory card or to dump attribute memory or tuple information from a PC Card.

The following are serial port drivers:

  • GPS

    A sample serial-based client PC Card driver based on a GPS PC Card.

  • TTY

    A sample serial-based client PC Card driver based on a sample teletypewriter (TTY) terminal.

For network driver interface specification (NDIS) drivers, NDIS sources consist of source code that is compatible with Windows 95 and Windows NT Workstation. The source code can simply be recompiled as a Windows CE–based DLL. For more information, see NDIS Network Drivers.


Audio Drivers

A waveform audio driver is responsible for processing messages from the Wave API Manager to play and record waveform audio. Waveform audio drivers are implemented as stream interface drivers that are loaded by the Device Manager. The sample waveform audio driver is named WaveDev.dll. All audio drivers use the prefix WAV to name their stream interface functions, yielding function names such as WAV_Open, WAV_IOControl, and so on.

Audio hardware typically supports a larger set of operations than usually apply to files. For example, files commonly do not have volume controls or playing speed controls, but audio hardware can and often does have them. Fortunately, the DeviceIOControl portion of the stream interface allows arbitrary operations on files, making it possible to manipulate audio hardware by means of WAV_IOControl. To send commands to the audio hardware, the operating system passes various messages to this function. For example, to prepare the audio hardware for recording, Waveapi.dll uses WAV_IOControl to send the WIDM_PREPARE message to the audio driver. The messages sent to the audio driver are similar to those used by user-mode audio drivers on Windows-based desktop platforms, such as Mmdrv.dll.

Because audio drivers rely entirely on DeviceIOControl function messages, the implementation of the remainder of the stream interface is relatively simple. Specifically, the WAV_Read, WAV_Seek, and WAV_Write functions are merely stubs that return constant values. The other stream interface functions should be fully implemented and follow the conventions described in the Reference for those functions.

As an alternative to implementing the stream interface directly, you can use the model device driver (MDD) library—Wavemdd.lib—supplied by Microsoft. This library implements the stream interface functions in terms of the audio device driver service-provider interface (DDSI) functions. If you use Wavemdd.lib, you must create a matching platform-dependent driver (PDD) library that implements the audio DDSI functions. The PDD library is generally called Wavepdd.lib, although there is no requirement that it be called this. These two libraries can then be linked together to form Wavedev.dll.

The following illustration shows the interaction of the audio driver with the Windows CE operating system.

As shown in the illustration, the first step in playing and recording sounds is a call from an application to the operating system. The operating system translates such calls into WAV_IOControl calls to the audio driver. The operating system component that performs this translation is the Wave API Manager. The audio driver then executes the appropriate actions on the hardware. The Device Manager only loads and registers the audio driver at startup time. It is not directly involved in the operation of the driver.

Like standard stream interface drivers, the audio driver uses registry keys both to store configuration information and to advertise itself to the operating system. If the audio driver is not already listed in Platform.reg, create a key called HKEY_LOCAL_MACHINE\Drivers\Builtin\Audio to store configuration information. The Device Manager creates a key in HKEY_LOCAL_MACHINE\Drivers\Active for the audio driver when the driver is loaded at startup time. Because the Device Manager only checks for audio drivers at startup time, drivers for add-on audio hardware still need to have their registry entries in the \Builtin\Audio part of the registry, although their hardware is not built into any Windows CE–based platform.

The following table shows the stream interface functions for the audio driver.

WAV_Close | WAV_PowerDown
WAV_Deinit | WAV_PowerUp
WAV_Init | WAV_Read
WAV_IOControl | WAV_Seek
WAV_Open | WAV_Write

For more information, see Developing Stream Interface Device Drivers.

The following table shows the DDSI functions for the audio driver.

PDD_AudioDeinitialize
PDD_AudioGetInterruptType
PDD_AudioInitialize
PDD_AudioMessage
PDD_AudioPowerHandler
PDD_WaveProc


Sample Audio Driver

The sample audio driver is a layered, interrupt-driven stream interface driver that drives a built-in audio device. The layers are the typical MDD and PDD layers that native device drivers use, although the device driver interface (DDI) functions in the MDD layer are the same as the stream interface functions used by ordinary stream interface drivers. This code is provided as a convenience and does not imply any restrictions in the way that audio hardware for Windows CE must function. An audio driver could be implemented that is monolithic, is polled, and that drives a peripheral device, if a user wants to do so. The sample audio driver MDD layer implements a single audio device capable of playing and/or recording pulse code modulation (PCM) waveform audio. The sample supports simultaneous recording and playing but may also be used with audio devices that can perform only one of those functions at a time. The PDD layer is responsible for communicating with the audio hardware to start and stop playing and recording and to initialize and de-initialize the hardware.


Playing and Recording

The basic operation for playing involves an interrupt and two direct memory access (DMA) buffers for output data. The Wave API Manager prepares the data blocks and sends them to the audio driver’s MDD layer. The MDD checks to see if the block has data to be played. If so, it calls the PDD_WaveProc function by using the WPDM_START message. The PDD is responsible for copying data from the block to the temporary DMA buffers. Then, the DMA is started to play the data. When the first of the two buffers is finished playing, an interrupt occurs. The PDD should report the interrupt to be of type AUDIO_STATE_OUT_PLAYING. If there is more data to be played, the MDD sends the message WPDM_CONTINUE. Otherwise, it sends WPDM_ENDOFDATA. As data blocks finish playing, the MDD marks them as done and sends them back to the Wave API Manager.

The PDD should alternate between the two DMA buffers, filling one buffer as the other is playing. If the reserve buffer is not full before the first buffer’s data is finished playing, the PDD layer should report this with the return value AUDIO_STATE_OUT_UNDERFLOW. This gives the MDD layer an opportunity to synchronize and continue playing.

Recording uses a mechanism that is similar to that used by playing, but in reverse order. Recording starts with the PDD message WPDM_START as before, but no data is copied until the first DMA buffer is full. Then, the PDD copies the data from the DMA buffer into the user block. Again, as blocks are filled, the MDD returns them to the Wave API Manager. Recording continues until the user application requests a stop and sends the WPDM_STOP message.


Interrupt Handling in Audio Drivers

The MDD layer is responsible for interrupt handling. It creates and manages the audio driver’s interrupt service thread (IST). The IST calls the PDD_AudioGetInterruptType function to determine the cause of the audio interrupt. Based on the interrupt type, the MDD either performs a callback to the Wave API Manager or sends more data or buffer space to the PDD to be played or recorded.

The PDD layer can support simultaneous playing and recording with one interrupt by merging the recording and playing status in the AUDIO_STATE return value for PDD_AudioGetInterruptType. The value can represent a state change of either the playing or recording hardware, or both. The lower 4 bits of the return code represent the input status, and the upper 4 bits represent the output status. If the current interrupt is for both recording and playing, the values can be combined using the logical OR operator. However, if the interrupt requires only one operation, the other 4 bits should remain 0; otherwise, the MDD interprets this as a change or update in the hardware’s status.

If your audio device uses more than one hardware interrupt—typically, one for playing and one for recording—the driver’s interrupt service routines (ISRs) should both return the interrupt ID specified by the PDD layer. When PDD_AudioGetInterruptType is called to determine the cause of the interrupt, the function can access the hardware to determine the actual playing or recording status for each interrupt event. If this mechanism is not suitable for your audio device, you must modify the sample MDD layer to handle multiple virtual interrupts and multiple ISTs.


Power Management in Audio Drivers

When the system goes into the suspend state, the Device Manager calls the audio driver’s WAV_PowerDown function. This function should call the PDD_AudioPowerHandler function to allow the PDD to put the hardware in a low power consumption mode if it is available. When the system resumes, the Device Manager calls the audio driver’s WAV_PowerUp function, which should also call PDD_AudioPowerHandler. WAV_PowerUp also calls the SetInterruptEvent function for the audio interrupt to allow any active handles to be released by the IST.


Audio Compression Manager Drivers

Audio Compression Manager (ACM) drivers are stream interface drivers. Like other stream interface drivers, ACM drivers are controlled by the Device Manager, and they expose standard stream I/O functions. However, unlike other stream interface drivers, applications do not use these drivers directly. ACM drivers are called by the ACM, which sends messages to ACM drivers when applications need to play or record sounds.

There are several key reasons to write an ACM driver:

  • To support a particular audio file format. For example, the .wav files on Windows-based platforms require ACM drivers that differ from ACM drivers for the .au files of Sun Microsystems. Similarly, audio files in other formats need customized ACM drivers.
  • To convert audio file format to another format. The ACM driver APIs can be used to load an audio file into a common format, which ACM drivers can then translate into their own format.
  • To use an encoding or compression algorithm tailored to the characteristics of a particular type of audio. For example, human speech has a relatively limited frequency range and many essentially silent periods. An ACM driver written with these characteristics in mind can produce recordings that require little memory and yet retain good sound quality.
  • To perform filtering of audio data. For example, an ACM driver could be used to filter a data stream out of an audio signal that contains speech in the lower frequencies and data in the higher frequencies.

An individual ACM driver can be written to perform a combination of these tasks.

All ACM drivers must use ACM as their device file name prefix. In Windows CE, the Index keys in the registry settings designate individual ACM drivers. Thus, multiple ACM drivers have special device file names such as “ACM1:”, “ACM2:”, and so on. A maximum of eight ACM drivers can coexist on a Windows CE–based platform; Index value 9 is reserved for the PCM converter exported from Waveapi.dll.

The ACM uses Index keys when searching for an ACM driver to perform format conversions. The ACM selects the first appropriate ACM driver that it finds. For more details about device file names, see Device File Name Prefixes. For more information about Index keys, see Device File Name Indexes.

ACM drivers respond to messages similar to those used by ACM drivers written for Windows NT. In fact, the Windows CE–based ACM functions and structures that ACM drivers use are the same as those described in the Windows NT Device Driver Kit. In Windows CE, the ACM uses the ACM_IOControl function to send messages to the driver. By calling this function, the ACM bypasses the three primary stream I/O functions: XXX_Read, XXX_Write, and XXX_Seek. Consequently, those functions are never called in an ACM driver. The ACM uses the other stream I/O functions only for setup and shutdown tasks.

The Windows NT Device Driver Kit contains several sample ACM drivers. You can port these drivers to work on any Windows CE–based platforms that your product targets, and you can modify the drivers to support additional audio format types and audio filter types. The Windows NT Device Driver Kit contains complete documentation on writing ACM drivers. For more information, see Porting a Windows NT ACM Driver to Windows CE.


Types of ACM Driver

There are three types of ACM driver:

  • Codec

    Codecs convert one audio format type to another format type; typically, a compressed format to an uncompressed format. A codec can convert a compressed format, such as MS-ADPCM, to an uncompressed format, such as PCM, which most audio hardware can play directly.

  • Converter

    Converters change one variety of a format to another variety of the same format. For example, a converter can convert a PCM audio stream sampled at 44 kHz to a PCM audio stream sampled at 11 kHz.

  • Filter

    Filters modify audio data without changing the format of the data. Filters generally are used to add some sort of audio effect to an audio stream. Tasks such as graphic equalization or adding an echo to an audio stream are appropriate for filters.


ACM Format Tags and Filter Tags

Format tags represent the names of individual formats, such as PCM. Filter tags represent the names of individual filters. Typical ACM drivers support one or more types of format or filter, or a combination of both. A set of formats or filters is associated with each of an ACM driver’s tags. For example, the sample IMAADPCM driver, a codec, supports the WAVE_FORMAT_PCM format tag for the PCM format type and WAVE_FORMAT_IMA_ADPCM for the IMAADPCM format type. For each format tag, the driver supports a set of individual formats, consisting of combinations of sample rates and sample sizes.

The main difference between codecs and converters is that codecs transform data from a format belonging to one format tag into a format belonging to another format tag, whereas converters transform data between two formats that belong to the same format tag.

The supported format tags and filter tags are declared in the Mmreg.h header file. If you write an ACM driver for a new format type or filter type, register your driver with Microsoft by using the Multimedia Developer Registration Kit.


ACM Driver Stream I/O Functions

The following table shows the ACM functions and their associated calls.

Function
Description
ACM_Init | Called by the Device Manager when the driver is loaded
ACM_Deinit | Called by the Device Manager when the driver is unloaded
ACM_Open | Called by the ACM when the driver is opened for use
ACM_Close | Called by the ACM when the driver is no longer needed
ACM_Read | Never called
ACM_Write | Never called
ACM_Seek | Never called
ACM_PowerUp | Called by the Device Manager when the system resumes from the suspend state
ACM_PowerDown | Called by the Device Manager when the system enters the suspend state
ACM_IOControl | Called by the ACM to pass messages to and receive information from the driver


ACM Driver Messages

The ACM passes the following messages to ACM drivers:

ACMDM_DRIVER_ABOUT
Requests that the driver display its About dialog box.
ACMDM_DRIVER_DETAILS
Requests that the driver return detailed information about its capabilities.
ACMDM_DRIVER_NOTIFY
Notifies the driver of changes to other ACM drivers.
ACMDM_FILTER_DETAILS
Requests information about a filter associated with a specified filter tag.
ACMDM_FILTERTAG_DETAILS
Requests information about a specified filter tag.
ACMDM_FORMAT_DETAILS
Requests information about the format associated with a specified filter tag.
ACMDM_FORMAT_SUGGEST
Requests that the driver suggest a target conversion format for a specified source format.
ACMDM_FORMATTAG_DETAILS
Requests information about a format tag.
ACMDM_HARDWARE_WAVE_CAPS_INPUT
Requests information about the input capabilities of the audio hardware.
ACMDM_HARDWARE_WAVE_CAPS_OUTPUT
Requests information about the output capabilities of the audio hardware.
ACMDM_STREAM_CLOSE
Requests that the driver close a conversion stream.
ACMDM_STREAM_CONVERT
Requests that the driver convert an audio stream.
ACMDM_STREAM_OPEN
Requests that the driver open a new audio stream.
ACMDM_STREAM_PREPARE
Requests that the driver prepare any buffers associated with an audio stream.
ACMDM_STREAM_RESET
Requests that the driver stop operations on an audio stream.
ACMDM_STREAM_SIZE
Requests that the driver return the size required for a source or destination buffer.
ACMDM_STREAM_UNPREPARE
Requests that the driver clear any prepared buffers associated with an audio stream.


Porting a Windows NT ACM Driver to Windows CE

To port an ACM driver from Windows NT to Windows CE, link the driver with the Acmdwrap.lib file, which provides the driver with the appropriate stream I/O interface. This library not only handles all interactions with the ACM and the Device Manager, but also passes messages from its ACM_IOControl function to the Windows NT ACM driver’s existing DriverProc function.


Printer Drivers

Windows CE versions 2.0 and later include support for printing. The printing model used by Windows CE is a subset of the printing model defined for desktop Windows-based platforms. Only a small number of the graphics driver functions defined for printer drivers are required in printer drivers for Windows CE.

The following sections of the Windows CE Device Driver Kit documentation describe the interaction between Windows CE–based printer drivers and Windows CE–based display mechanisms. These sections also describe the functions that printer drivers must implement and the port monitor functions that printer drivers call to send data to printers.

The Windows CE Graphics Display Interface (GDI) and display driver perform most of the work involved in printing. At the beginning of the printing process, the GDI creates a device context (DC) with attributes retrieved from the printer driver during a call to the DrvEnablePDEV function. The display driver is used to render subsequent drawing commands issued from the application into the DC; the printer driver does not render the document. Then, the GDI sends the resulting bitmap to the printer driver so that the printer driver can format it and send it to the printer. To conserve memory, the GDI renders the document in bands, which are horizontal sections of the page, and makes several calls to the printer driver to send the rendered bands to the printer.

Windows CE–based printer drivers are required to implement only those graphics driver functions necessary for gathering printer metrics, for setting up the printer, for starting and ending print jobs, and for preparing rendered strips for printing. Internally, the printer driver converts the bitmap data from a GDI bitmap format into the format required by the printer. This can include operations such as color reduction to the color space of the printer, data compression, and data conversion into the format used by the printer, a format sometimes known as a printer description language. Finally, the printer driver calls the port monitor to send the rendered strips to the printer.

Windows CE–based printer drivers are compiled as dynamic-link libraries (DLLs). As a result, they must export the DrvEnableDriver function.

For more information about Windows CE–based printer drivers, see Functions Implemented by Printer Drivers and Registry Keys for Printer Drivers.


Functions Implemented by Printer Drivers

The following table shows the functions that Windows CE–based printer drivers must implement.

Function
Description
DrvCopyBits | Called by the GDI to copy a rendered band to the printer driver. During the call to the DrvEnablePDEV function, the printer driver specifies the bitmap format used in the call to this function.
DrvDisablePDEV | Frees memory and resources used by the driver when the printer device context (DC) is no longer needed.
DrvDisableSurface | Called by the GDI to inform the printer driver that the surface created for the current printing DC is no longer needed.
DrvEnableDriver | Receives two callback function pointers from the GDI and returns GDI function pointers for the other entry points implemented by the printer driver. This function is the entry point for the printer driver DLL, which must be exported in the .def file for the DLL.
DrvEnablePdev | Used by the GDI to gather device metrics for the target printer. The printer driver returns device specifics in the GDIINFO structure.
DrvEnableSurface | Creates a surface for use in rendering by calling the EngCreateDeviceSurface function.
DrvEndDoc | Called by the GDI to finish or abort a print job.
DrvGetModes | Returns information to the GDI about the default printing mode supported by the printer driver. The printer driver returns the default configuration in the DEVMODE structure.
DrvStartDoc | Called by the GDI to start a print job.
DrvStartPage | Called by the GDI to start printing the next page of a print job.


Port Monitor Functions Used by Printer Drivers

The port monitor manages all communication between printer drivers and physical communication ports on a Windows CE–based platform. Therefore, the printer driver does not need to support different types of printer ports explicitly; due to the port monitor’s management, the driver automatically works with any type of printer port. The port monitor supports serial ports, infrared ports, parallel ports, and network printing. Printer drivers should call the port monitor APIs, instead of calling low-level communication APIs directly.

The following table shows the port monitor functions.

Function
Description
GetPrinterInfo | Retrieves information about the capabilities of a printer.
PrinterClose | Closes a handle to a printer.
PrinterOpen | Opens a handle to a printer.
PrinterSend | Sends blocks of data to a printer.


Registry Keys for Printer Drivers

Windows CE uses registry keys to store both global printer settings for the device and configuration information for individual printer drivers. The keys are stored under KEY_LOCAL_MACHINE\Printers\ in the registry. For information on registry keys that relate to the default printer and to the ports available for printing, see Global Printer Settings. For information on registry keys for specific printer drivers, see Printer Driver Settings.


Global Printer Settings

The global printer settings stored in the registry list the I/O ports to use for printing, provide a global time-out value, and store which printer driver currently is selected as the default. The default printer driver is stored as a value for DefaultPrinter. The printer ports are stored as values in the \Ports subkey.

The following registry file excerpt defines five printer ports, two time-out values, and the default printer driver.

[HKEY_LOCAL_MACHINE\Printers\Ports]
  "Port1"="COM1: 9600"
  "Port2"="COM1: 57600"
  "Port3"="IRDA"
  "Port4"="LPT1:"
  "Port5"="NET0:"
[HKEY_LOCAL_MACHINE\Printers\Settings]
  "TimeOut"=dword:1E
[HKEY_LOCAL_MACHINE\PrintSettings]
  "TimeOut"=dword:2D
[HKEY_LOCAL_MACHINE\Printers]
  "DefaultPrinter"="PCL Laser"

The values correspond to serial ports at 9,600 baud and 57,600 baud, an infrared port, a parallel port, and a network printer port. For the two “COM1:” ports, a baud also is specified. The port monitor parses the values to extract the baud and device file name. In Windows CE 2.0, “COM3:” is assumed to be an infrared port. However, in Windows CE 2.10 and later the new file name “IRDA” is reserved for the infrared port, whereas “COM3:” is used for an additional serial port. When assigning an infrared port for printing, the value of the key for the port must be the literal string “IRDA”, even though this value is not in the standard format for special Device File Names. The names “LPT1:” and “NET0:” are reserved for parallel and network printing, respectively, although the Device File Name Indexes in those names can be any valid value.

Windows CE versions 2.02 and later use the TimeOut key. This value is a hexadecimal number measured in seconds; the example is for a 30 second time-out. After the time-out period, the printer driver can display a dialog box to give the user the option to retry or cancel. In this example, the default printer driver, “PCL Laser”, is the name of a subkey within HKEY_LOCAL_MACHINE\Printers\ where Windows CE can find settings for the Printer Control Language (PCL) laser printer driver.

For a printer that does not use the parallel port, such as an infrared or serial printer, it is difficult for Windows CE to determine whether the printer has received all the data to be printed. Therefore, a time-out parameter is used to detect and report printing errors if the printer fails to give any signal that it is still active. This time-out value is stored in the PrintSettings\TimeOut key. The default value is 45 seconds.

The value stored in the DefaultPrinter key lists the printer that is preselected in the common print dialog box that applications display to users.


Printer Driver Settings

Settings for individual printer drivers are stored in subkeys of the HKEY_LOCAL_MACHINE\Printers\ registry key. The registry key for a printer driver should define four keys: Driver, High Quality, Draft Quality, and Color. The Driver value names the DLL that contains the printer driver. The High Quality and Draft Quality values store the resolution of high-quality and draft-quality modes, if the printer supports them. Not all printers support a draft-quality mode, so the Draft Quality key may be omitted. The High Quality key must always be present, and it corresponds to the highest-quality mode of the printer. The Color value defines whether a printer can print in color or only in monochrome. If color is supported, this key must be set to the literal string “COLOR” so that the common print dialog box enables color printing for applications.

The following example shows settings for the PCL laser printer driver and the PCL Inkjet printer driver.

[HKEY_LOCAL_MACHINE\Printers\PCL Laser]
  "Driver"="pcl.DLL"
  "High Quality"="300"
  "Draft Quality"="150”
  "Color"="Monochrome"
  "Version"="0x200"

[HKEY_LOCAL_MACHINE\Printers\PCL Inkjet]
    "Driver"="pcl.dll"
    "High Quality"="300"
    "Draft Quality"="150"
    "Color"="Monochrome"

In addition, the Version key can be used to support printer drivers that serve multiple printers.


Display Drivers

Like much of Windows CE, the display driver interface (DDI) is a subset of the Windows NT DDI. If you are unfamiliar with the Windows NT DDI, you may find it helpful to read the display driver sections of the Windows NT Device Driver Kit before writing your Windows CE–based display driver.

Windows CE uses only the basic graphics engine functions and driver functions from the Windows NT DDI. The differences between Windows CE and Windows NT have the following ramifications on Windows CE–based display drivers.

  • Windows CE–based display drivers always present the same functionality; therefore, the Graphics Device Interface (GDI) does not query a driver for information about its capabilities.
  • A Windows CE–based display driver cannot reject an operation as too complex, and then call back into GDI to have the operation broken into simpler primitives. Because all Windows CE–based display drivers support the same functionality, the GDI can break up complex operations before calling the display driver.
  • Windows CE–based display drivers are compiled as dynamic-link libraries (.dll) rather than libraries (.lib).

In Windows CE version 2.0 and later, the GDI makes calls to the display driver, and the display driver writes to the physical display device. All Windows CE–based display drivers must implement a set of Display Driver Interface (DDI) functions, which are used to initialize the display driver and draw to the display.

Most Windows CE display drivers use a set of C++ classes called the Graphics Primitive Engine (GPE). The GPE classes serve as a base of code that you can use to derive new display drivers for your hardware. The GPE classes handle all communication within the DDI layer. Using the GPE classes can save a large amount of development and debugging work. The S3Virge and all other sample display drivers included in the Windows CE Platform Builder use the GPE. They demonstrate how you can add extensions to the display driver, for example, to enable hardware accelerations.


Display Driver Interface

In Windows CE, display drivers are native drivers because there is a custom interface between them and the Graphics, Windowing, and Events subsystem (GWES). They are loaded and called directly by their parent process, which can be either the GWES module or the Device Manager. Windows CE display drivers are most commonly written using a layered architecture. The GPE library provided by Microsoft handles all the default drawing, acting as the display driver’s model device driver (MDD) layer. OEMs or independent hardware vendors (IHVs) write the hardware-specific code that corresponds to the display driver’s platform-dependent driver (PDD) layer. Display driver writers can minimize the amount of time and effort needed to create a display driver by customizing one of the sample drivers provided in the Platform Builder. The display drivers in the Platform Builder represent a variety of display hardware devices. All of the sample drivers take advantage of the GPE to provide default drawing with hardware-specific issues addressed in the driver samples.


Primary Display Driver

If a Windows CE–based platform includes a display, Windows CE loads the default, or primary, display driver when the system starts up. By default, GWES loads a display driver named Ddi.dll. If the optional HKEY_LOCAL_MACHINE\System\GDI\Drivers\Display registry key is present, GWES loads the display driver indicated by that key. If the platform’s version of Windows CE is configured to include windowing, the Window Manager uses the frame buffer supported by the primary display driver for all on-screen drawing.

In order to perform a drawing operation, an application must first get a device context (DC) for a window or the desktop, by calling the CreateWindow and GetDC functions. The resulting DC is the application’s drawing surface. If the application’s Windows CE–based platform does not include support for windowing, and thus has no Window Manager, the application must call the CreateDC function with the name of the primary display driver’s .dll file to create a DC directly.


Secondary Display Drivers

In addition to the primary display, Windows CE–based platforms can support additional display devices. These additional controllers might be used, for example, to support a VGA output to a CRT screen. Display drivers for such additional display devices are called secondary display drivers. Secondary display drivers are only loaded when an application calls the CreateDC function with the name of the secondary display driver’s .dll file. CreateDC returns a handle to a DC that is associated with the secondary display driver. An application can use this DC just like a DC associated with the primary display driver; all of the text and graphics APIs work with the DC. However, applications may not use any Window Manager functions with the DC because the Window Manager was not involved in creating it. Thus, applications are responsible for rendering the entire display on the secondary display device. If you want to create the appearance of windows, menus, dialog boxes, scroll bars, and so on, on the secondary display, your application must draw those items itself, using the text and graphics APIs. If you want to show the contents of the primary display on the secondary display, your application can copy the frame buffer for the primary display to the frame buffer for the secondary display. The secondary display driver is unloaded when there are no remaining DCs associated with it. When multiple display devices are being used, the GDI makes sure that all drawing calls are routed to the appropriate display driver.

Windows CE–based platforms can provide a built-in secondary display controller. The controller must be managed by a secondary display driver. The secondary display driver must be implemented as an ordinary Windows CE display driver, and expose the same DDI as other display drivers.

If the display controller resides on a removable medium, such as a PC Card, the secondary display driver can be implemented as two DLLs or as a single DLL. In practice, most device driver writers choose to implement two separate DLLs: a secondary display driver that exposes the native display driver DDI and a stream driver that exposes the 11 stream interfaces. The Device Manager loads the stream interface driver when a user connects the display adapter to the system and registers the driver’s special device file name, for example, “VGA1:”. The secondary display driver is loaded when an application calls CreateDC and passes in the name of the secondary display driver’s .dll file. The secondary display driver gets a handle to the stream interface driver by calling the FileOpen function on the “VGA1:” special device file. The secondary display driver handles all of the graphics processing. When it needs to communicate with the display controller, it uses the stream interface driver’s IOControl function.

You may choose to create a single DLL that acts as both secondary display driver and stream driver instead. In this case, the Device Manager loads this combined driver in its own process space to serve as an ordinary stream interface driver, whereas GWES would load the same driver in its process space to act as the secondary display driver. If you choose to implement a combined driver, be aware that because the driver DLL is loaded in separate process spaces, it cannot share global data without using shared memory or a memory-mapped file. Furthermore, having the driver loaded twice wastes system resources.

Many of the stream interface functions are not used by display device drivers because display devices are not particularly oriented to working with streams of data. Display drivers need only have stubs for those functions. For these interfaces, the driver should handle the call and return. The driver’s XXX_Init and XXX_Deinit functions are exceptions. The driver should handle calls to these functions correctly, as described in Developing Stream Interface Drivers. The Device Manager calls XXX_Init when the display adapter is connected to the system. When the adapter is disconnected, the Device Manager calls XXX_Deinit. XXX_Deinit deletes any data structures and registry entries that were created by the driver’s XXX_Init function.

Like all PCMCIA-based drivers, the stream interface driver must create Registry entries that enable the device to be detected. For more information, see Registry Keys for Display Drivers.


Using Secondary Display Drivers with Pocket PowerPoint

The Microsoft® Pocket PowerPoint® application can use secondary displays if the display driver maintains certain registry keys when it is loaded and unloaded. At initialization, the driver should create a subkey for itself within the HKEY_LOCAL_MACHINE\Drivers\Display\Active key. This key is used to specify the secondary display driver’s DLL name, as well as the driver’s buffer and tap information. For more information, see Registry Keys for Display Drivers. For removable display adapters, such as PC Card–based adapters, this initialization should take place when the Device Manager calls the display driver’s XXX_Init function.

Pocket PowerPoint loads the secondary display driver’s DDI library by calling the CreateDC function with the secondary display driver’s DDI library name. For example, if the Drivers\Display\Active\Voyager\Dll subkey has the value PCARDVGA.DLL, Pocket PowerPoint calls CreateDC and passes the string PCARDVGA.DLL as an input parameter.

After the driver loads and initializes, Pocket PowerPoint calls the GetDeviceCaps function to identify the display device’s resolution and color depth. The secondary display driver typically stores this information internally. When the driver supports multiple resolutions and those resolutions are selected by a separate application, such as a Control Panel application, this information may optionally be kept in the registry.

When the secondary display driver is unloaded, it should remove the Drivers\Display\Active subkey that it created during initialization. This indicates that the driver is no longer available. For removable display adapters, this de-initialization should take place when the Device Manager calls the drivers XXX_Deinit function after a user disconnects the display adapter from the system.


DDI Functions

All Windows CE–based display drivers must implement the DDI functions listed here. However, only DrvEnableDriver must be exported from the display driver’s DLL, which means that only DrvEnableDriver must bear this exact name. You can customize the names for the other functions because they are exposed to the GDI through function pointers returned by DrvEnableDriver. Of course, no matter what names you give these functions, they must follow the prototypes in the Winddi.h header file.

Function
Description
DrvAnyBlt | Bit block transfer, with stretching or transparency.
DrvBitBlt | General bit block transfer, with clipping and masking.
DrvContrastControl | Enables software adjustment of the display hardware’s contrast.
DrvCopyBits | Sends a GDI-created print band to a printer driver.
DrvCreateDeviceBitmap | Creates and manages bitmaps.
DrvDeleteDeviceBitmap | Deletes a device bitmap.
DrvDisableDriver | Notifies the display driver that the GDI no longer needs it and is ready to unload the driver.
DrvDisablePDEV | Notifies the driver that the GDI no longer needs a particular display device.
DrvDisableSurface | Notifies the driver that the GDI no longer needs a particular drawing surface.
DrvEnableDriver | The initial entry point exposed by the driver, which returns pointers to the other DDI functions to the GDI.
DrvEnablePDEV | Returns a PDEV structure, a logical representation of a physical display device, to the GDI.
DrvEnableSurface | Creates a drawing surface and associates it with a PDEV.
DrvEndDoc | Sends any control information needed to finish printing a document.
DrvEscape | Used for retrieving information from a device that is not available in a device-independent DDI. This function is the same as in Windows NT, except that Windows CE does not support the DrvDrawEscape function.
DrvFillPath | Fills a drawing path with a brush.
DrvGetMasks | Gets the color masks for the display device’s current mode.
DrvGetModes | Lists the display modes supported by the display device
DrvMovePointer | Moves the pointer with a guarantee that the GDI will not interfere with the operation.
DrvPaint | Paints a specified region with a brush.
DrvPowerHandler | Called to handle POWER_UP and POWER_DOWN notifications.
DrvQueryFont | Gets font metric information.
DrvRealizeBrush | Creates a brush with parameters specified by the GDI.
DrvRealizeColor | Maps an RGB color onto the closest available color supported by the device.
DrvSetPalette | Sets the display device’s palette.
DrvSetPointerShape | Sets the pointer to a new shape and updates the display.
DrvStartDoc | Sends any control information needed to start printing a document.
DrvStartPage | Sends any control information needed to start printing a new page.
DrvStrokePath | Renders a drawing path.
DrvTransparentBlt | Bit block transfer, with transparency.
DrvUnrealizeColor | Maps a color in the display device’s format onto an RGB value.


Using the Graphics Primitive Engine Classes

All sample display drivers included with the Platform Builder use the Graphics Primitive Engine classes. Although the GPE classes are optional, using them greatly facilitates the process of writing display drivers. If you use the GPE classes, you need only provide the new code necessary to make your display hardware operate correctly and perform acceleration.

The GPE classes require that your display hardware use a flat-frame buffer; that is, the display’s memory must lie in a contiguous memory range. Modifying the GPE classes to use a non-contiguous frame buffer would require significant effort.

To create a display driver based on the GPE classes

  1. Create a directory for your project.
  2. Copy the files from one of the sample driver directories, such as the S3Trio64 directory, to your project directory.
  3. Replace all device-specific names in those files, such as S3Trio64, with your device’s name.
  4. Change the Config.cpp file so that it places your display device in a linear frame-buffer mode.
  5. Disable all hardware-specific acceleration.
  6. Build and test this non-accelerated driver.
  7. Add your own hardware acceleration code.

For more information about GPE classes and methods, see the Reference.


GDI Support Services for Display Drivers

The Windows CE GDI provides some services to support display drivers as predefined structures. The structures interact both with associated functions and with a few stand-alone C functions. Predefined structures provide support for brushes, palettes, translations, clipping regions, and stroke and fill paths. Stand-alone C functions provide support for device bitmaps and surfaces. The following table shows the structures and functions.

Structure or function
Description
BRUSHOBJ | Structure that represents a brush used for solid or patterned stroke and fill operations
BRUSHOBJ_pvAllocRbrush | Function that allocates memory for a brush
BRUSHOBJ_pvGetRbrush | Function that retrieves a pointer to the specified brush
CLIPOBJ | Structure that represents a clipping region
CLIPOBJ_bEnum | Function that enumerates clipping rectangles from a clipping region
CLIPOBJ_cEnumStart | Function that sets parameters for enumerating the rectangles in a clipping region
EngCreateDeviceBitmap | Function that causes the GDI to create a handle for a device bitmap
EngCreateDeviceSurface | Function that causes the GDI to create a device surface that the display driver manages
EngDeleteSurface | Function that informs the GDI that a device surface no longer is needed by the display driver
PALOBJ_cGetColors | Function that copies colors into a palette
PATHDATA | Structure that stores portions of a drawing path
PATHOBJ_bEnum | Function that enumerates PATHDATA records from a drawing path
PATHOBJ_vEnumStart | Function that readies a drawing path to have its component line segments enumerated
PATHOBJ_vGetBounds | Function that returns the bounding rectangle for a drawing path
XLATEOBJ | Structure used in translating colors from one palette to another
XLATEOBJ_cGetPalette | Function that retrieves colors from an indexed palette


Accelerating Bit Block Transfers and Line Drawing

Display drivers do much of their work by means of a few basic operations. Thus, if you make those operations faster, you greatly improve the overall performance of your display driver. The operations that account for the bulk of a display driver’s work are bit block transfers (blits) and line drawing. Any operation that transfers a rectangular group of pixels from main memory to display memory is a blit. Such operations include drawing rectangles that are filled with solid colors, displaying icons, and displaying cursors. Line drawing, for the purposes of acceleration, is limited to drawing straight lines.

These types of acceleration can be done either in hardware or in software. Hardware acceleration for blits and line drawing is generally faster but is not available in all display hardware. However, even if your display hardware cannot accelerate the functions, you may still be able to achieve better performance than the default provided by the GPE classes. For example, you can write routines that take advantage of the specific characteristics of your display hardware to perform blits and draw lines as efficiently as possible.

The capabilities of display hardware vary considerably. Simple display hardware requires that every pixel of the display be set by the display driver. Such hardware cannot accelerate blits or line drawing. Display hardware that is more complex can effectively complete those tasks much faster than a display driver can.

The following sections describe how to support both hardware and software acceleration of blit and line drawing operations in your display driver. The Platform Builder includes sample display drivers that illustrate both hardware and software acceleration.


Accelerating Bit Block Transfers

With Windows CE 2.0 and later, a display driver can use up to three levels of blit processing: the default blit emulation provided by the GPE, the software acceleration provided by the emulation library or by your own custom code, and the hardware acceleration supported by the display device hardware. The display driver can choose, based on the parameters of individual operations, which method to use for each blit that it performs.

The Platform Builder provides the GPE library, which is located under Public\Common\OAK\Lib. This class library, offered in binary form, serves as the foundation for Windows CE–based display drivers. The GPE supplies default processing for blits in its EmulatedBlt function.


Emulation Library for Software-Accelerated Blits

Windows CE provides sample code for creating an emulation library for software-accelerated blits. The sample code is located under Public\Common\OAK\Drivers\Display\Emul in the Platform Builder. The library contains emulated blit functions with destination pixel depths of 2, 8, and 16 bits per pixel. You can use the emulated blits to improve performance over the default blit processing provided in the GPE. Of particular interest to embedded system developers, the source code can serve as a template for writing additional software-accelerated blits tailored to the display hardware.


Sample Blit Acceleration

By default, a display driver routes all blits to the GPE. As alternatives, a display driver can route blit handling to the emulation library or directly to the hardware.

The S3Virge display driver serves as a model to demonstrate how a display driver can invoke all three of these methods. The S3Virge sample code is located under Platform\CEPC\Drivers\Display\S3Virge in the Platform Builder.

The following code example is drawn from the sample S3Virge display driver contained in the Platform Builder. It shows how blit processing begins when the GDI calls the driver’s BltPrepare function. The driver initializes the blit parameters and determines which function to use to perform the individual blits. Typically, the driver initializes the GPE to handle default blit processing. The following code example shows this initialization.

SCODE
S3Virge::BltPrepare(GPEBltParms *pBltParms)
{
    // Put debug messages and optional timing processing here.

    pBltParms->pBlt = EmulatedBlt; // Generic BLT processing

For improved performance, BltPrepare can examine the characteristics of the blit and the associated display surfaces to determine whether an accelerated blit is appropriate. After the initialization code, the display driver can contain code for hardware or software accelerations. The sample driver includes or excludes this code at compilation time. The ENABLE_ACCELERATION preprocessor directive specifies inclusion of the code for hardware accelerations. The ENABLE_EMULATION directive specifies inclusion of the code for software-accelerated emulation.

After setting the default handler, the S3Virge driver dispatches blits to hardware acceleration, if available, and then to software-accelerated emulation, if available. The driver defines a macro that simplifies calls to functions in the emulation library. Next, it checks whether the destination surface is in video memory. This is an important check that most display drivers must make before using hardware acceleration because the GDI uses the display driver to render printer output, as well as display output. Printer output is rendered in system memory, not in video memory. Most display hardware is able to perform accelerated drawing in only two situations: when the destination surface is in video memory, for blits without a source surface, or when both the source and destination surfaces are in video memory, for blits with a source surface. Therefore, if the hardware has this limitation, the driver must check the source and destination surfaces before calling the acceleration function.

The following code example shows how the driver evaluates the raster operation (ROP) code and directs the blit to a supported hardware acceleration, when available. The SRCCOPY ROP illustrates how the driver checks for a source surface in video memory before invoking hardware acceleration.

#ifdef ENABLE_ACCELERATION

#define FUNCNAME(basename) (SCODE (GPE::*)(struct GPEBltParms *))Emulator::Emulated##basename

    if ( pBltParms->pDst->InVideoMemory() ) {

switch( pBltParms->rop4 )
    {
        case 0x0000:    // BLACKNESS
            pBltParms->solidColor = 0x0;
            pBltParms->pBlt = (SCODE (GPE::*)
(struct GPEBltParms *)) AcceleratedFillRect;
            break;
        case 0xFFFF:    // WHITENESS
            pBltParms->solidColor = 0xffffff;
            pBltParms->pBlt = (SCODE (GPE::*)
(struct GPEBltParms *))AcceleratedFillRect;
            break;

        case 0xF0F0:    // PATCOPY
        case 0x5A5A:    // PATINVERT
            if (pBltParms->pLookup || pBltParms->pConvert)    // Emulate Color Convertion
            {
                RETAILMSG(VIRGE_VERBOSE_MSGS, (TEXT("S3Virge::Blt - Emulate Color Conversion\r\n")));
                break;
            }
            if (pBltParms->solidColor == -1)
            {
                RETAILMSG(VIRGE_VERBOSE_MSGS, (TEXT("S3Virge::Blt - PATCOPY - patterned brush\r\n")));
                DEBUGWAIT(GPE_ZONE_BLT_LO)
                pBltParms->pBlt = (SCODE (GPE::*) (struct GPEBltParms *)) AcceleratedPatCopyBlt;
            }
            else
            {
                RETAILMSG(VIRGE_VERBOSE_MSGS, (TEXT("S3Virge::Blt - PATCOPY - solid brush\r\n")));
                DEBUGWAIT(GPE_ZONE_BLT_LO)
                pBltParms->pBlt = (SCODE (GPE::*) (struct GPEBltParms *)) AcceleratedFillRect;
            }
            break;
        case 0x6666:    // SRCINVERT
        case 0x8888:    // SRCAND
        case 0xCCCC:    // SRCCOPY
        case 0xEEEE:    // SRCPAINT
            // can't accelerate if src not in video memory
            // can't accelerate color translations
            if (!pBltParms->pSrc->InVideoMemory() || pBltParms->pLookup || pBltParms->pConvert)
                break;

            if (pBltParms->bltFlags & BLT_STRETCH)
            {
                // Stretch blit
                RETAILMSG(VIRGE_VERBOSE_MSGS,(TEXT("Stretch Blt!\r\n")));
                break;
            }
            pBltParms->pBlt = (SCODE (GPE::*) (struct GPEBltParms *)) AcceleratedSrcCopyBlt;
            break;

The following code example for the S3Virge display driver shows how to use the blit emulation library. After setting the default blit handler and handling hardware accelerations, the driver checks for possible software accelerations. When available, it sets the blit function pointer to the corresponding function in the emulation library.

Before invoking a blit function in the emulation library, the driver must check for conditions that would prevent the blit from using emulation. This is critical because the functions in the emulation library require that the driver validate the blit before calling an emulation function. In the previous example, the driver checked for a solid brush because the emulation library does not support pattern brushes. The emulation library also cannot handle color conversions, bit depth conversions, stretching, and transparency. The following code example shows how the driver checks that none of these restrictions apply.

if (pBltParms->pBlt == EmulatedBlt) {
        //
        // Cancel any parameter values that would make this
        // blit non-emulatable.
        //
        if (!(EGPEFormatToBpp[pBltParms->pDst->Format()] != 8        ||
             (pBltParms->bltFlags & (BLT_TRANSPARENT | BLT_STRETCH)) ||
             pBltParms->pLookup                                      ||
             pBltParms->pConvert))

After confirming that the emulation library functions can perform a blit, the display driver examines the ROPs, dispatching supported ROPs to the appropriate function. For simplicity, the driver specifies the ROP4 value. For masking blits, the entire WORD is relevant. For non-masking blits, only the least significant byte, the ROP3 value, is relevant. ROPs are defined as DWORDs for compatibility with Windows-based desktop platforms, although Windows CE–based display drivers use only the most significant WORD of an ROP value. Windows CE–based display drivers ignore the lower WORD, which contains ROP compiler directives. The following code example shows how the display driver checks the ROP4 value to choose which blit function to use.

switch (pBltParms->rop4)
    {
        case 0x0000:    // BLACKNESS
            pBltParms->solidColor = 0;
            pBltParms->pBlt = FUNCNAME(BltFill08);
break;
        case 0xFFFF:    // WHITENESS
            pBltParms->solidColor = 0x00ffffff;
            pBltParms->pBlt = FUNCNAME(BltFill08);
break;
        case 0xF0F0:    // PATCOPY
            if( pBltParms->solidColor != -1 )
            {
                pBltParms->pBlt = FUNCNAME(BltFill08);
            }
            break;


Additional Accelerated Sample Drivers

Like the S3Virge display driver, other display drivers provided in the Platform Builder demonstrate how to invoke hardware accelerations and how to make use of the emulation library.

The S3Trio64 driver is in the Platform\CEPC\Drivers\Display\S3Trio64 directory. The S3Trio64 driver demonstrates support for hardware accelerations and use of the emulation library. The driver also supports blit handling for both 8-bpp and 16-bpp destination surfaces. For example, in the case of a mask PATCOPY text blit with a 1-bpp mask, the driver uses the emulation library’s BltText16 function to handle the blit. With a 4-bpp mask, the driver uses the emulation library’s BltalphaText16 function.

if (pBltParms->pBlt == EmulatedBlt) {
#ifdef FB16BPP
    switch (pBltParms->rop4)
    {
        case 0xAAF0:
// Special PATCOPY ROP for text output--fill where mask is set.
            // If the brush is not a pattern brush
            if( (pBltParms->solidColor != -1) &&
                (pBltParms->pDst->Format() == gpe16Bpp) )
            {
                WaitForNotBusy();
                if (pBltParms->pMask->Format() == gpe1Bpp)
                {
                    pBltParms->pBlt =
FUNCNAME(BltText16);
                    return S_OK;
                }
                else   // Antialiased text
                {
                    pBltParms->pBlt =
FUNCNAME(BltAlphaText16);
                    return S_OK;
                }
            }
            break;
        default:  // Other ROP4s
            ;
    }

For hardware accelerations and use of the emulation library, see the Citizen driver under Platform\ODO\Drivers\Display\Citizen.


Accelerating Line Drawing

Windows CE 2.0 and later include support for accelerating line drawing. The levels of accelerated line drawing are largely the same as for accelerated blit operations. The discussion of Accelerating Bit Block Transfers in the previous sections is relevant for line drawing as well, except that the emulation library provided in the Platform Builder does not provide software-accelerated line drawing. Developers can add software-accelerated line drawing functions, if necessary.

Display drivers route line drawing to the GPE, to custom software acceleration routines, or directly to the hardware. The following code example from the S3Virge display driver sample shows how these methods are invoked. This source code is very similar in design to the acceleration processing performed for blit operations.

SCODE
S3Virge::Line(GPELineParms *pLineParms, EGPEPhase phase)
{

#ifdef ENABLE_ACCELERATION
    if (phase == gpeSingle || phase == gpePrepare)
    {
        DispPerfStart (ROP_LINE);
        pLineParms->pLine = EmulatedLine;
        if (pLineParms->pDst->InVideoMemory() && pLineParms->mix == 0x0d0d)
        {
#if VIRGE_VERBOSE_MSGS
            switch (phase)
            {
            case gpeSingle:
                RETAILMSG(VIRGE_VERBOSE_MSGS, (TEXT("in single\n\r")));
                break;
            case gpePrepare:
                RETAILMSG(VIRGE_VERBOSE_MSGS, (TEXT("in prepare\n\r")));
                break;
            }
#endif
            SelectSolidColor(pLineParms->solidColor);
            pLineParms->pLine = (SCODE (GPE::*)(struct GPELineParms *)) AcceleratedSolidLine;
        }
    } else if (phase == gpeComplete) {
        DispPerfEnd (0);
    }
#else
    pLineParms->pLine = EmulatedLine;
#endif
    return S_OK;
}

The S3Virge driver conditionally compiles the hardware acceleration code with the ENABLE_ACCELERATION preprocessor directive. Line drawing begins with a call to the driver’s Line function. For improved performance, the driver’s Line function can examine the characteristics of the line drawing and the associated surfaces to determine whether an accelerated form of line drawing is appropriate. The default line drawing function is set to the EmulatedLine function of the GPE. The driver checks for a destination surface in video memory and checks the line drawing parameters. If the parameters are valid for acceleration, the line drawing function is set to the driver’s AcceleratedSolidLine function.


Functions in the Emulation Library

The emulation library includes the following functions. Developers can add additional functions, if necessary.

EmulatedBltAlphaText02
Special-case fast blit function for rendering antialiased text. Assumes mask surface containing the 4-bpp alpha bitmap for the glyph.
File name
ROP
Source bit depth
Target bit depth
ebalph02.cpp AAF0 – 02

EmulatedBltAlphaText16
Special-case fast blit function for rendering antialiased text. Assumes mask surface containing the 4-bpp alpha bitmap for the glyph.
File name
ROP
Source bit depth
Target bit depth
ebalph16.cpp AAF0 – 16

EmulatedBltSrcCopy0202
Implements blit(SRCCOPY)
File name
ROP
Source bit depth
Target bit depth
ebcopy02.cpp CCCC 02 02

EmulatedBltSrcCopy0808
Implements blit(SRCCOPY)
File name
ROP
Source bit depth
Target bit depth
ebcopy08.cpp CCCC 08 08

EmulatedBltSrcCopy1616
Implements blit(SRCCOPY)
File name
ROP
Source bit depth
Target bit depth
ebcopy16.cpp CCCC 16 16

EmulatedBltDstInvert02
Implements Patblt(DSTINVERT)
File name
ROP
Source bit depth
Target bit depth
ebdinv02.cpp 5555 – 02

EmulatedBltDstInvert08
Implements Patblt(DSTINVERT)
File name
ROP
Source bit depth
Target bit depth
ebdinv08.cpp 5555 – 08

EmulatedBltFill02
Implements Patblt(PATCOPY) for ROP F0F0, Patblt(BLACKNESS) for ROP 0000, Patblt(WHITENESS) for ROP FFFF
File name
ROP
Source bit depth
Target bit depth
ebfill02.cpp 0000, FFFF, F0F0 – 02

EmulatedBltFill08
Implements Patblt(PATCOPY) for ROP F0F0, Patblt(BLACKNESS) for ROP 0000, Patblt(WHITENESS) for ROP FFFF
File name
ROP
Source bit depth
Target bit depth
ebfill08.cpp 0000, FFFF, F0F0 – 08

EmulatedBltFill16
Implements Patblt(PATCOPY) for ROP F0F0, Patblt(BLACKNESS) for ROP 0000, Patblt(WHITENESS) for ROP FFFF
File name
ROP
Source bit depth
Target bit depth
ebfill16.cpp 0000, FFFF, F0F0 – 16

EmulatedBltPatInvert02
Implements Patblt(PATINVERT)
File name
ROP
Source bit depth
Target bit depth
ebpinv02.cpp 5A5A – 02

EmulatedBltPatInvert08
Implements Patblt(PATINVERT)
File name
ROP
Source bit depth
Target bit depth
ebpinv08.cpp 5A5A – 08

EmulatedBltSrcAnd0202
Implements blit(SRCAND)
File name
ROP
Source bit depth
Target bit depth
ebsand02.cpp 8888 02 02

EmulatedBltSrcAnd0808
Implements blit(SRCAND)
File name
ROP
Source bit depth
Target bit depth
ebsand08.cpp 8888 08 08

EmulatedBltSrcAnd1616
Implements blit(SRCAND)
File name
ROP
Source bit depth
Target bit depth
ebsand16.cpp 8888 16 16

EmulatedBltSrcInvert0202
Implements blit(SRCINVERT)
File name
ROP
Source bit depth
Target bit depth
ebsinv02.cpp 6666 02 02

EmulatedBltSrcInvert0808
Implements blit(SRCINVERT)
File name
ROP
Source bit depth
Target bit depth
ebsinv08.cpp 6666 08 08

EmulatedBltSrcInvert1616
Implements blit(SRCINVERT)
File name
ROP
Source bit depth
Target bit depth
ebsinv16.cpp 6666 16 16

EmulatedBltSrcPaint0202
Implements blit(SRCPAINT)
File name
ROP
Source bit depth
Target bit depth
ebspnt02.cpp EEEE 02 02

EmulatedBltSrcPaint0808
Implements blit(SRCPAINT)
File name
ROP
Source bit depth
Target bit depth
ebspnt08.cpp EEEE 08 08

EmulatedBltSrcPaint1616
Implements blit(SRCPAINT)
File name
ROP
Source bit depth
Target bit depth
ebspnt16.cpp EEEE 16 16

EmulatedBltText02
Special-case fast blit function for rendering solid-color filled text with a mask
File name
ROP
Source bit depth
Target bit depth
ebtext02.cpp AAF0 – 02

EmulatedBltText08
Special-case fast blit function for rendering solid-color filled text with a mask
File name
ROP
Source bit depth
Target bit depth
ebtext08.cpp AAF0 – 08

EmulatedBltText16
Special-case fast blit function for rendering solid-color filled text with a mask
File name
ROP
Source bit depth
Target bit depth
ebtext16.cpp AAF0 – 16


Supporting Antialiased Fonts

Antialiased fonts work on any device whose display driver supports them. Typically, antialiasing is supported on devices that are not palettized. If the display driver supports antialiased fonts, it must notify the GDI of this capability at system startup. It does this by returning GCAPS_GRAY16 from the GetGraphicsCaps function. The S3Trio64 sample display driver demonstrates how to support antialiasing. The driver source code is located in the Platform\Cepc\Drivers\Display\S3trio64 directory.


Supporting ClearType

Windows CE versions 2.12 and later support Microsoft ClearType font technology. ClearType dramatically improves font sharpness on color LCD displays. If the display driver supports ClearType, it must notify the GDI of this capability at system startup by returning GCAPS_CLEARTYPE in the call to the GetGraphicsCaps function. The Citizen sample display driver demonstrates how to support ClearType. The driver source code is located in the Platform\Odo\Drivers\Display\Citizen directory.

The display driver invokes a software emulation to render a ClearType glyph. For example, in the Citizen driver, text output with a solid brush is usually routed to the BltText08 emulation function. For the edge pixels on the glyph, the display function pointer is set to a special BltCleartype emulation for the 3-3-2 palette and the Halftone palette.

case 0xAAF0:    // Special PATCOPY ROP for text output--fill where mask
         //is 1.
        // Not a pattern brush?
        if( pBltParms->solidColor != -1 )
        {
            if (pBltParms->pMask->Format() == gpe1Bpp)
            {
                DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("CITIZEN::Blt - 0xAAF0\r\n")));
                pBltParms->pBlt = FUNCNAME(BltText08);
                return S_OK;
            }
            else if (pBltParms->pMask->Format() == gpe8Bpp)  // ClearType
            {
                DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("CITIZEN::Blt ClearType - 0xAAF0\r\n")));
                pBltParms->pBlt = FUNCNAME(BltCleartypeHalftoneText08);
//                pBltParms->pBlt = FUNCNAME(BltCleartype332Text08);
                return S_OK;
            }
        }
        break;


Including Display Drivers in an OS Image

OEMs can include the emulation library and the GPE class library in their Windows CE OS image. The emulated blit functions are compiled and linked into a single library called Emul.lib. The display driver links to this library through a link directive in the driver’s Sources file. For example, the Sources file for theS3Trio64 display driver includes Emul.lib in its list of target libraries. This links the driver with Emul.lib. As mentioned, the Platform Builder provides the GPE library in binary form. The GPE library is also included in the driver’s Sources file.

The Platform.bib file in the Platform\Cepc\Files directory directs the RomImage tool, the tool that creates operating system images for Windows CE, to include the appropriate driver in the OS image. See the Platform Builder for complete documentation on using the Romimage tool and creating OS images.

If you are building a platform from one of the sample Platform.bib files provided in the Platform Builder, you can change which display driver the Romimage tool puts into the OS image. The Platform.bib file in Platform\Cepc\Files directs the Romimage tool to include the S3Trio64 driver in the OS image. Other display drivers may take the place of S364Trio. See Platform.bib for the list of environment variables that may be set to direct the Romimage tool to use a different display driver. The 2BPP driver is the default display driver for the Windows CE hardware reference platform. The Platform.bib file in Platform\Odo\Files lists the environment variables that may be set to direct Romimage to use a different display driver.


Testing Display Drivers

The Platform Builder includes a sample application, VideoApp, that the display driver writer can use to test a display driver. The application tests the driver’s ability to draw lines, polygons, rectangles, text, cursors, and to display various color patterns. The application source code is located in the Platform\Cepc\Test\Videoapp directory. The VideoApp.exe is located in the Platform\Cepc\Drivers\Display\Test directory.

Testing a new driver with the VideoApp application verifies that the driver correctly performs a number of common graphics operations. The application is not intended as an exhaustive test of all possible operations. The display driver writer is responsible for thorough testing of the driver.


Profiling Display Driver Performance

The Platform Builder includes a sample profiling tool, DispPerf, that the display driver writer can use to profile the performance of a display driver. DispPerf builds a table that lists, for each ROP code that is profiled, the frequency count, elapsed time, in microseconds, and average elapsed time, in microseconds, for ROPs handled by the default GPE emulation, by the software emulation library, and by hardware accelerations. To measure these times accurately, DispPerf can be used only on Windows CE–based platforms that support the QueryPerformanceCounter and QueryPerformanceFrequency functions with a recommended resolution of 1 microsecond.

The S3Virge driver demonstrates how to use the profiler for measuring performance of blits and line drawing. The display driver writer may extend the profiler to measure the performance of additional display functions. Source code for DispPerf is in the Platform\Cepc\Drivers\Display\S3virge\Dispperf directory.

The driver starts profiling of blit operations during the call to the BltPrepare function when it calls the DispPerfStart function. The following code example shows how the driver initializes its display function pointer to use the default emulation provided by the GPE.

SCODE
S3Virge::BltPrepare(GPEBltParms *pBltParms)
{

    DispPerfStart (pBltParms->rop4);

    pBltParms->pBlt = EmulatedBlt; // Catch all.

When the driver is able to handle the ROP with hardware acceleration or software emulation, it changes its display function pointer appropriately. The driver also calls the DispPerfType function to record which type of acceleration is used to handle the ROP. For example, the following code example demonstrates how the driver calls DispPerfType after the driver successfully sets the display function pointer to a hardware-accelerated function.

// Performance Logging Type
    if (pBltParms->pBlt != EmulatedBlt) {
        DispPerfType(DISPPERF_ACCEL_HARDWARE);
    }

When the blit operation completes, the BltComplete function stops profiling with a call to the DispPerfEnd function.

The DO_DISPPERF environment variable controls whether the code to support profiling is compiled into the display driver. Refer to the Sources file for the S3Virge driver to see how the environment variable causes the correct compiler directives to be set.

DispPerf can be invoked from the Command Shell on a Windows CE–based platform, or it can be launched remotely from the Windows CE Debug Shell. The following example shows the command syntax for DispPerf.

dispperf [-c[w*]] [-d [> file]]

The -c option clears the profiler buffer. If the letter “w” appears one or more times following the -c option, DispPerf calls the CreateWindow function that number of times and profiles the resulting display driver operations. The -d option dumps the profiler buffer in tabular form. If the -d option is followed by “>“ plus a file name, the output is written to the named file. Otherwise, it appears on the console where the command was issued.

The following example shows how DispPerf clears its buffer of all profiling information.

Dispperf –cwwwwwd

It then calls the CreateWindow function five times, profiling the performance of the display functions. The following example shows how DispPerf outputs its table of profiling information to the console.

Dispperf –c
Pword stat_rpt.pwd
Dispperf –d > results.txt

In this example, DispPerf clears its buffer of all profiling information. The Microsoft® Pocket Word application is launched and opens the document Stat_rpt.pwd. DispPerf tracks the profiled display functions called by Pocket Word. Finally, DispPerf writes its table of profiling information to the Results.txt file.


Display Buffer Formats

The Windows CE GDI supports displays with a wide variety of color depths and color models, ranging from 1-bit color to palettized color to true 32-bit RGB color. Each format also supports several pixel orderings, depending on whether access to the display memory is by bytes, WORDs, or DWORDs.

For all display buffer formats, the order of pixels on the display is from left to right and top to bottom. That is, pixel (0,0) appears at the upper-left corner of the display, and pixel (width–1, height–1) appears at the lower-right corner. For more information about the arrangement of video memory for each display buffer format that Windows CE supports, see the following sections:

  • Using 1 Bit per Pixel
  • Using 2 Bits per Pixel
  • Using 4 Bits per Pixel
  • Using 5 or 6 Bits per Pixel
  • Using 8 Bits per Pixel
  • Using 15 or 16 Bits per Pixel
  • Using 24 Bits per Pixel
  • Using 32 Bits per Pixel


Using 1 Bit per Pixel

The 1-bpp format is for simple black-and-white displays. Black is represented by 0, and white is represented by 1. Pixel (0,0) is packed into the highest-order bit of the first byte of display memory. The following illustration shows the arrangement of memory for the format.


Using 2-Bits per Pixel

The 2-bpp format typically is used for four-level grayscale displays, although any four-entry palette works. The following table shows the bits for the associated gray levels.

Bit 1
Bit 0
Gray level
0 | 0 | Black
0 | 1 | Dark gray
1 | 0 | Light gray
1 | 1 | White

The following illustration shows the arrangement of memory for the format.


Using 4 Bits per Pixel

The 4-bpp format usually is a palettized format. The frame buffer itself can be implemented either as 2 pixels packed into each byte or as 1 pixel per byte. The following illustration shows the arrangement of memory for the format.

If you choose to implement just 1 pixel per byte, the driver should represent the display mode as 8 bpp with a 16-color palette. The relevant bits in each byte should be the 4 lowest bits; the 4 highest bits should always be 0. For more information on formats in which single pixels do not fill entire bytes, see Using 5 or 6 Bits per Pixel Format. For best results, use the following standard Windows CE 16-color palette.


Using 5 or 6 Bits per Pixel

The 5 or 6-bpp format should always use a whole byte for each pixel. The relevant bits must be the low-order bits in the pixel, with unused high-order bits containing 0s.

With displays that use 5 or 6 bpp, you can choose either to palettize the colors or to use the bits in the pixel to represent the colors directly. For example, you can make 6 bpp a 64-entry palettized display, or you can use the 6 bits in each pixel to represent four levels each of red, green, and blue directly. The following illustration shows the arrangement of memory for the format.


Using 8 Bits per Pixel

The 8-bpp format ideally should use a software-changeable palette that maps 8-bit values onto 24-bit colors. For better performance, compatibility, and image quality, Microsoft recommends using a palette that contains the default Windows CE palette, although this is not required. The following illustration shows the arrangement of memory for the format.

‹ [image] ›


Using 15 or 16 Bits per Pixel

The 15 or 16-bpp format is a masked, non-palettized format. For either 15 or 16 bpp, 1 pixel is stored in each 2-byte WORD. The 15-bpp format wastes the high-order bit of each word. The following table shows the masks that Microsoft recommends to extract red, green, and blue values.

Color
16-bit mask
16-bit mask
Red | 0x7C00 | 0xF800
Green | 0x3E00 | 0x07E0
Blue | 0x001F | 0x001F

As the masks show for 15 bpp, the low-order 15 bits of each word contain the pixel data. The unused bit should contain 0. The following illustration shows the arrangement of memory for the format.


Using 24 Bits per Pixel

The 24-bpp format is a true-color format, in which each pixel stores 8 bits for red, green, and blue. The advantage of this format is that image quality is very good. Because each pixel occupies exactly 3 bytes, the pixels can be packed together without wasting memory. The drawback is that because half the pixels in this scheme cross DWORD boundaries, there is a performance penalty in accessing and decoding pixels. The following illustration shows the arrangement of memory for the format.


Using 32 Bits per Pixel

Like the 24-bpp format, the 32-bpp format is a true-color format. Unlike the 24-bpp format, however, the 32-bpp format does not cause pixels to cross DWORD boundaries, although this format is less efficient in memory use. There are two ways to arrange the color channels in this format. One method puts blue in the least significant byte of each pixel, and the other method puts red in the least significant byte. These options correspond to the PAL_BGR and PAL_RGB modes. Microsoft recommends using PAL_RGB for slightly better performance. The following table shows the masks that you can use to extract red, green, blue, and alpha channels from each pixel.

Color
PAL_RGB mask
PAL_BGR mask
Red | 0x000000FF | 0x00FF0000
Green | 0x0000FF00 | 0x0000FF00
Blue | 0x00FF0000 | 0x000000FF

If your product does not use an alpha channel, use 0x00000000 as the mask for alpha. The following illustration shows the arrangement of memory for the format.


Display Hardware Recommendations

For display hardware used with Windows CE, Microsoft makes several recommendations to improve performance and to facilitate driver development. Following the recommendations enables you to implement your display driver more easily, although you can write a fully functional driver even if your hardware does not conform to these recommendations.

Microsoft strongly recommends that your display hardware uses a linear-frame buffer. All the display’s memory should be contiguous, and one linear-access window should cover the entire frame buffer. If your hardware does not meet these qualifications, you must make substantive modifications to the GPE classes, if you choose to use them. For more information, see Using the Graphics Primitive Engine Classes.

Your display hardware should use a supported combination of pixel format, packing, and pixel ordering. For more information, see Display Buffer Formats. The display hardware’s frame buffer should have the following properties:

  • Top-down format, with pixel (0,0) at the top left and pixel (width-1, height-1) at the lower right.
  • The frame buffer’s stride—the number of bytes in memory that it takes to represent one scan line on the display—should be a multiple of 4 bytes, even if this means padding the end of each scan line with unused bytes.
  • The entire frame buffer must be accessible by the CPU without requiring the CPU to perform bank selection.
  • Frame buffers should not use bit planes, in which separate frame buffers are used for each color channel or intensity component.

Microsoft also recommends using display hardware that can accelerate the following operations, in order of decreasing importance:

  • Solid-color fills, specifically, blit operations whose pbo->iSolidColor member is not 0xFFFFFFFF.
  • SRCCOPY blit operations.
  • Cursor display, if your platform uses a cursor.
  • Solid-line drawing with sub-pixel precision.
  • Masked SRCCOPY blit operations.


Registry Keys for Display Drivers

When a Windows CE–based platform contains a display driver, it is automatically loaded by GWES at system startup. By default, GWES loads a driver named Ddi.dll. To change the name of the default display driver, use the HKEY_LOCAL_MACHINE\System\GDI\Drivers\Display registry key to override the default display driver DLL name. The registry key should be placed in your Platform.reg file.

[HKEY_LOCAL_MACHINE\System\GDI\Drivers]
    Display="DDI.DLL"

The device driver writer can optionally include a registry key that provides additional information about the driver. This information is not used by the GDI, but may be useful to application programs. It may also be useful to the driver when it supports, for example, multiple resolutions, which a user can select from a Control Panel application provided by the display driver writer. In this case, the driver could examine the registry to determine which resolution to set when the display driver loads. The following example shows a registry key for a native display driver that supports a Color Graphix Voyager PCMCIA-based display device. The key stores the native driver’s DLL name, screen size, and color depth.

[HKEY_LOCAL_MACHINE\Drivers\Display\PCARDVGA]
    Dll="PCARDVGA.DLL"
    CxScreen=Dword:280
    CyScreen=Dword:F0
    Bpp=Dword:8


Registry Keys for Removable Display Adapters

When a secondary display adapter is provided on removable hardware, such as a PC Card, the display driver is typically implemented as two drivers: a native driver that exposes the native DDI and a stream interface driver that exposes the stream interfaces. The stream driver must initialize the Registry with the keys that allow it to be detected and loaded. When the PC Card is inserted, the Device Manager initiates a detection sequence to determine what driver should service the card. If the PC Card has a Plug and Play ID, it is used to determine which driver to load. Otherwise, the Device Manager tries the detection functions for all the PC Card drivers installed on the system until one of them reports that it recognizes the PC Card. Once the correct driver is located, the Device Manager loads the driver whose name is provided as the registry key along with the detection function that succeeded in detecting the PC Card. The following example shows how the Device Manager then loads the driver, registers its special device file name, and calls the driver’s XXX_Init function.

 [HKEY_LOCAL_MACHINE\Drivers\PCMCIA\VoyagerVGA]
    Dll="VOYAGER.DLL"
    Prefix="VGA"
    Index=Dword:1

[HKEY_LOCAL_MACHINE\Drivers\PCMCIA\Detect\60]
    Dll="VOYAGER.DLL"
    Entry="DetectVGA"

As discussed earlier, the Microsoft Pocket PowerPoint application needs additional registry keys in order to use secondary display adapters. During initialization, the driver should update the HKEY_LOCAL_MACHINE\Drivers\Display\Active key with the information appropriate for its driver. This includes information about the native driver .dll name, as well as Buffer and Tap information. For removable display adapters, this initialization should take place when the adapter is connected to the system and the Device Manager calls the stream driver’s XXX_Init function. The following example shows how this is done.

[HKEY_LOCAL_MACHINE\Drivers\Display\Active\Voyager]
    Dll="PCARDVGA.DLL"
    BufferMode=Dword:0
    Tapmode=Dword:0

The following table shows the four available values for BufferMode.

Value
Description
bmNotShared | There is no common frame buffer.
bmTopHalf | The top half of the secondary display is also shown on the system’s built-in LCD display.
bmSquashed | A scaled-down version of the secondary display is also shown on the system’s built-in LCD display.
bmOff | The system’s built-in display is turned off while the driver is active.

The following table shows the three available values for Tapmode.

Value
Description
tmNone | The display driver performs no conversion of any tap coordinates.
tmScaled | The display driver scales tap coordinates to match the secondary display’s resolution.
tmUndefined | The display driver always reports tap coordinates of (0,0), but still reports tap events.


Universal Serial Bus Drivers

The universal serial bus (USB) is an external bus architecture for connecting USB-capable peripheral devices to a host computer. USB is not designed to be used as the internal bus for connecting CPUs to main memory and to devices that reside on a motherboard. Instead, USB is a communication protocol that supports serial data transfers between a host system and USB-capable peripherals. USB technology was developed as a solution to the increasing user demands on computers and the need for flexible and easy-to-use peripherals. USB technology directly affects a number of standard peripherals, such as keyboards, joysticks, mouse devices, digital cameras, computer telephone integration (CTI), and video-conferencing products.

USB offers the following benefits to system designers and users:

  • USB provides a single, well-defined, standard connector type for all USB devices. This simplifies not only the design of USB devices, but also a user’s task of determining which plugs correspond to which sockets.
  • USB eliminates the need for separate mouse, modem, keyboard, and printer ports, thus reducing hardware complexity.
  • USB supports hot plugging, which means that USB devices can be safely connected and disconnected while the host is turned on. Other generic peripheral connection standards, such as the Small Computer Systems Interface (SCSI), require that the host be turned off when peripherals are added or removed.
  • USB supports Plug and Play. When a USB device is plugged in, the host computer identifies the device and configures it by loading the appropriate driver.
  • USB provides flexibility in how devices are powered. USB devices can draw power directly from the USB cable (bus-powered devices), supply their own power from batteries or from a wall socket (self-powered devices), or use a combination of both types of power.
  • USB supports power-saving suspend and resume modes.
  • USB offers a high-speed 12-megabits-per-second mode and a low-speed 1.5-megabits-per-second mode that support a variety of peripherals.
  • USB guarantees certain amounts of bandwidth for devices that cannot tolerate non-continuous transmission that comes in bursts, such as streaming audio and video devices.
  • USB offers four different data transfer types suited to the needs of various types of peripheral.
  • USB enables multiple peripherals to communicate simultaneously with the host.

Consult the following sources for additional information about USB technology that is important both for OEMs who add USB support to their Windows CE–based platforms and for independent hardware vendors (IHVs) who build USB peripherals:

  • USB Implementers Forum Web site

    This site contains the complete USB specification, Universal Serial Bus Specification, Revision 1.0.

  • Intel Corporation Web site

    This site contains information on USB hardware and microcontroller chips, such as the 8x930Ax and 8x931xA series chips.

Note The official Universal Serial Bus Specification uses the term function to refer to USB-capable peripheral devices. However, because function typically refers to callable units of C/C++ code, Windows CE documentation uses the term “USB device” to refer to USB peripherals. In addition, the official Universal Serial Bus Specification uses the term “USB client driver” to refer to device drivers for USB devices, but to avoid confusion with client/server terminology, this documentation uses the term “USB device driver.”


USB Architecture

A USB system consists of a host computer, one or more USB devices, and a physical bus. The host consists of two layers: an upper software layer, which includes USB device drivers, and a host controller hardware layer, also known as an adapter layer. The main responsibility of the host computer is to control data transfers to and from USB devices. USB devices are peripherals that use the USB electrical and data format specifications to communicate with the host computer. The physical bus is the set of USB cables that links the controller with the peripherals.


USB Topology

USB is a tree-structured bus, which in the vocabulary of the Universal Serial Bus Specification is a star-tier topology. The host computer contains a single root node, or hub, of the USB tree. This hub mediates between its host computer and any peripheral devices. Hubs have exactly one connection, called an upstream port, to higher levels in the USB tree. Hubs can have up to seven downstream ports for connecting peripheral devices and other hubs. By connecting hubs together, up to 127 devices can be attached to the host computer. Peripheral devices are always leaf nodes within a USB bus. However, as a matter of practical implementation, many USB peripheral devices have hubs integrated into them, so users typically do not need to purchase separate USB hubs.

The following illustration shows a USB bus with several common peripherals connected. This illustration is modeled after the diagram of a typical USB bus configuration in the Universal Serial Bus Specification, Revision 1.0, but with the hubs and peripheral devices represented more explicitly.

The association of the mouse with the keyboard’s internal hub and the speakers with the monitor’s internal hub is entirely arbitrary. For example, a user could instead connect the mouse to the monitor’s internal hub, the modem to the keyboard’s internal hub, and the speakers to the stand-alone hub in Tier 1 without affecting the system’s functionality and without having to reconfigure any software on the host computer.


USB Transfer Types

Windows CE 2.10 supports all four types of data transfer defined in the Universal Serial Bus Specification, Revision 1.0. Device drivers for USB devices can use any of the following transfer types, as appropriate:

  • Control transfers

    Control transfers are bidirectional transfers used by the USB system software mainly to query, configure, and issue certain generic commands to USB devices. Control transfers can contain 8, 16, 32, or 64 bytes of data, depending on the device and transfer speed. Control transfers typically take place between the host computer and the USB device’s endpoint 0, but vendor-specific control transfers may use other endpoints.

  • Isochronous transfers

    Isochronous transfers provide guaranteed amounts of bandwidth and latency. They are used for streaming data that is time-critical and error-tolerant or for real-time applications that require a constant data transfer rate. For example, an Internet telephony application that carries a conversation in real time is a good candidate for isochronous transfer mode. Isochronous data requires guaranteed amounts of bandwidth and guaranteed maximum transmission times. For isochronous transfers, timely data delivery is much more important than perfectly accurate or complete data transfer.

  • Interrupt-driven transfers

    Interrupt-driven transfers are used mainly to poll devices to check if they have any interrupt data to transmit. The device’s endpoint descriptor structure determines the rate of polling, which can range from 1 through 255 milliseconds. This type of transfer is typically used for devices that provide small amounts of data at sporadic, unpredictable times. Keyboards, joysticks, and mouse devices fall into this category.

  • Bulk transfers

    Bulk transfers are for devices that have large amounts of data to transmit or receive and that require guaranteed delivery, but do not have any specific bandwidth or latency requirements. Printers and scanners fall into this category. Very slow or greatly delayed transfers can be acceptable for these types of device, as long as eventually all of the data is delivered.


USB Host Controller

The host controller, or adapter, is a hardware layer contained within the host computer. The host controller converts data between the format used by the host computer and the USB format. Only OEMs who implement Windows CE–based products using USB need to write drivers for USB host controllers. For more information, see Developing Native Device Drivers


USB Devices

USB peripheral devices consist of one or more physical components that implement the abilities of the devices. These components are called interfaces. Each interface typically provides some useful grouping of functionality, but exactly what constitutes an interface is an implementation detail. For example, a USB mouse device could present one interface for horizontal and vertical movement information and a separate interface for left and right button information. As another option, the device could present a single interface containing all the information. Both are valid approaches, but each approach has implications for how the device driver must operate.

Associated with each interface is a set of endpoints. Endpoints are the ultimate producers or consumers of data transmitted across the bus. All USB devices have a special endpoint, known as endpoint 0, which supports the generic USB status and configuration protocol.

USB device drivers establish logical communication channels, called pipes, to the various endpoints on a USB device. A pipe is a software association between a USB device driver and an endpoint. Pipes can be thought of as communication channels that use function calls to the USB system software to communicate with their associated endpoints. The characteristics of a pipe, such as the direction of communication and the required bandwidth, are determined by the endpoint characteristics, which in turn are indicated in the endpoint descriptor structure.

The bus interface hardware on a USB device is responsible for the transmission and the reception of USB-structured data. The logical USB device corresponding to a physical USB device consists of USB abstraction entities, such as the device endpoints and their corresponding pipes.


USB System Software

USB system software consists of two layers: an upper layer of USB device drivers and a lower layer of USB functions implemented by Windows CE. USB device drivers use the USB functions to establish connections to the devices they control and to configure and communicate with the devices. The lower layer of USB functions performs several interrelated tasks:

  • Managing all communication between USB device drivers and the host computer’s built-in USB root hub
  • Loading and unloading USB device drivers at the appropriate times
  • Translating data to and from the USB protocol’s frame and packet formats
  • Performing generic configuration and status-related tasks by establishing communication with the generic endpoint on all USB devices

The lower layer is itself composed of two parts—the upper universal serial bus driver (USBD) module and the lower host controller driver (HCD) module. The USBD module implements the high-level USBD interface functions in terms of the functionality provided by the HCD module. USB device drivers use the USBD interface functions to communicate with their peripherals.

Independent hardware vendores (IHVs) and manufacturers of USB devices should make use of the functions provided by the USBD to implement their USB device drivers. OEMs are responsible for providing an HCD module to their Windows CE–based platforms so that their hardware properly interfaces with the USBD module.

The following illustration shows the two layers of software in the context of the host’s USB hardware and a peripheral device.

During a data transfer, the flow of operation typically proceeds in the following sequence:

  1. A USB device driver initiates transfers by using USBD interface functions to issue requests to the USBD module.
  2. The USBD module divides requests into individual transactions, based on its knowledge of the bus and on characteristics of the USB devices connected to the bus.
  3. The HCD module schedules these transactions over the bus.
  4. The host controller hardware performs or completes the transactions.

All transactions on the bus originate from the host side; the peripherals are totally dependent.

The following sections on USB system software describe the various components of USB support in Windows CE 2.10. The primary goal of Microsoft USB support, aside from enabling IHVs to write device drivers for USB devices, is to help OEMs expand existing USB support on their platforms. Currently, USB support includes only the host side of the USB specification, which enables Windows CE to support USB peripherals. OEMs are free to add device-side support, which would enable Windows CE–based platforms to serve as USB peripherals to other USB hosts.


Supported and Unsupported USB Features

Windows CE 2.10 supports the following USB features:

  • Bus enumeration

    Windows CE supports enumeration of USB devices on the bus. The bus enumeration process is a multistep query sequence: the HCD module acquires information from a connected device, assigns it a unique USB address, and sets a configuration value. Once enumeration is complete, the device is configured and ready to conduct, transmit, and receive transactions. At this point, the USBD module attempts to load one or more USBDs to control the device, based on the information contained in the device and interface descriptors. If no suitable driver has been registered for the device, a user is prompted to enter the name of a driver to control the device.

  • Power management

    Windows CE provides support for bus-powered and self-powered devices. For both types of device, the USBD module reads the power requirements of the device from the descriptor information and rejects the device if it exceeds the maximum power threshold. OEMs can set the current-draw limit, so IHVs should not rely on any particular amount of available current, except as detailed in the Universal Serial Bus Specification, Revision 1.0.

  • Transfer types

    As mentioned, Windows CE supports all four types of data transfer defined in the Universal Serial Bus Specification. USB device drivers can use any of the transfer types that are appropriate for their peripherals. However, Windows CE 2.10 does not support the control transfers defined in the Universal Serial Bus Specification, Revision 1.0 to put a USB device into the suspend state. Depending on device capabilities, however, a USB device driver may be able to suspend the device by using the SetConfiguration function to deconfigure the device.

  • Class drivers

    The USB architecture implemented in Windows CE supports loading class drivers, although Microsoft does not supply any sample class drivers. Examples of device classes include the stream class and the human input device (HID) class, among others. OEMs or IHVs can write their own class drivers and load them appropriately, using the registry mechanism.

There is no support on Windows CE 2.10 for making a Windows CE–based platform itself appear as a USB peripheral to other host computers. That is, the HCD and USBD modules supplied by Microsoft in Windows CE do not provide facilities to connect a Windows CE–based platform to a desktop computer running as a USB host.


USB Power Management

Windows CE provides full support for power management of USB devices, as described in the Universal Serial Bus Specification, Revision 1.0. Very important for Windows CE are support for suspending and resuming because Windows CE–based platforms have a power-on and startup cycle that differs from the one on desktop computers. Support for bus-powered and self-powered USB devices is also important because many Windows CE–based platforms have limited power resources. For more information about power management, see Developing Native Device Drivers.

Windows CE supports power cycling USB devices in association with the standard Windows CE power states. When Windows CE issues a POWER_DOWN notification, the HCD module suspends the USB host controller hardware and all devices. When power returns to the platform, Windows CE sends a POWER_UP notification to the HCD module. When the host controller hardware has been re-initialized, the USBD module unloads the USB device drivers loaded prior to the POWER_DOWN notification, identifies all the USB devices currently connected to the bus—a process called bus enumeration—and loads the USB device drivers for those devices. This power cycle processing is very similar to that performed by the Windows CE Device Manager for PC Card devices.

This implies that USB device drivers may need to take special action to make a power cycle transparent to upper-level applications. For example, if a USB device provides a file system, the device driver should preserve open file handles across a power cycle. There are several ways to accomplish this. One solution is for the USB device driver to register itself with the Device Manager as a stream interface driver by calling the RegisterDevice function. This increments the reference count on the USB device driver’s DLL so that when the USBD module unloads the driver, the driver’s code still remains in memory. The USB device driver could keep any application file handles open and wait for the the call to the USBDeviceAttach function, which occurs after the system resumes and the USB device is ready to be used. The disadvantage of this approach is that the driver remains in memory even after the USB device is detached from the system. The second solution is to separate the USB interface from the upper-level file system interface. For example, the PC Card FAT file system module uses this approach to separate its file system driver code, which must manage file handles, from the PC Card driver code that actually manages the PC Card hardware.

Windows CE versions 2.12 and later provide full support for bus-powered and self-powered USB devices. When a user connects any self-powered or bus-powered device to a Windows CE–based platform, the USB system software automatically accepts or rejects the device, based on the device’s power requirements and the system’s overall power load. The power model is identical for both self-powered and bus-powered devices.

When a USB device is attached to a platform, the HCD module sets the initial power configuration. During the device attachment processing phase, the HCD module reads the power requirements of the USB device configurations from the device configuration descriptor structures. It then calls in to the platform-specific portion of the HCD module to determine if the host platform can support the USB device’s power requirements. An OEM can implement code in the platform-specific portion of the HCD module to test system power status, such as whether the system is running on batteries or is plugged into a power outlet, to assist in making this determination. In this way, the HCD module can choose an appropriate power configuration for the USB device from those listed in the device’s configuration descriptor structures.

At this time, Windows CE 2.10 does not support placing a USB peripheral into suspend mode programmatically.


Writing USB Device Drivers

This section describes how to write device drivers for USB devices running on Windows CE. USB device drivers exist to make the services of peripheral devices available to applications. Although there are no standard mechanisms that USB devices must use to accomplish this, there are various strategies that USBDs can adopt, depending on the nature of the peripherals that they control:

  • Use the stream interface functions

    A USBD can expose the stream interface functions. Applications can then treat the peripheral device as a file and use standard file I/O functions to interact with the device. However, because the Device Manager is not involved in the loading and unloading of USBDs, any USBD that exposes the stream interface functions must register and deregister its special device file name manually, using the RegisterDevice and DeregisterDevice functions. These functions should be called when the USBD is loaded and unloaded, respectively.

  • Use the existing Windows CE API

    By interacting with a Windows CE API, USB device drivers can indirectly expose certain types of peripheral to applications if Windows CE has an existing API appropriate to the peripheral. For example, USBDs for mass storage devices, such as hard drives and CD-ROM drives, can expose such devices through the standard installable file system interface. The sample USB mouse driver also uses this strategy. The driver does not expose the mouse device directly to applications; rather, it interacts with existing Windows CE APIs to submit the correct input events to the system. Thus, the USB nature of the mouse device is transparent to applications.

  • Create a custom API specific to a particular USBD

    This strategy does not place any restrictions on the way that a USBD exposes a device. It allows you to create an API for the device that best maps to the ways that applications are likely to use it. However, you must provide appropriate documentation to application writers so that their applications can use the driver.


USBD Interface Functions

USB device drivers interact with the peripherals that they control by using the USBD interface functions. These functions, which are provided by the USBD module, constitute the core of a USB device driver’s functionality. There are several categories of USBD interface functions, each related to a different aspect of interacting with a USB device, including transfer, pipe, frame, and configuration functions, as well as functions for performing other miscellaneous tasks.

Transfer functions are the most important category because they handle sending data to and receiving data from a USB device. There are four basic types of transfer: control, bulk, interrupt, and isochronous. For convenience, there are several special transfer functions that provide common types of control transfer, such as device configuration and setup requests. All transfer functions have an optional callback parameter. If a callback function is provided, the transfer functions return immediately, or asynchronously, without waiting for the transfer request to complete. When the transfer request finishes, the transfer function calls the function pointed to by the callback parameter. Additionally, a USB device driver can use the USB_NO_WAIT flag to cause the transfer functions to return asynchronously, even if no callback is specified. USB device drivers typically do this in situations when they queue several requests to the device and wait for only the last one to finish. In such cases, the device driver is still responsible for closing all transfer handles. If the USB device driver provides no callback function and does not use the USB_NO_WAIT flag, the transfer function blocks until the transfer is complete.

The USBD module calls the callback function in a context that may block other USB operations. Therefore, these callback functions should perform very minimal processing, preferably just setting some state variables and signaling an event so that any substantial post-processing can be handled by another thread. In particular, such callback functions cannot call any USBD interface functions. See the HID and mouse sample drivers for examples of using callback functions.

Internally, the USB system is optimized for a page size of 4 KB. If a platform has a different page size, the USB system allocates an internal, contiguous 4-KB buffer to use for data transfers. However, copying data into and out of this buffer may impose an unacceptable limit on the performance of a USB device driver. In such cases, the driver may pass an optional physical memory address that the USB system uses directly for data transfers. A driver-specific buffer used in this way must be contiguous within 4-KB segments and must not be accessed by the USB device driver during transfer operations. The LockPages function can be used to obtain physical address information.

The following table shows the transfer functions.

AbortTransfer | IssueControlTransfer
CloseTransfer | IssueInterruptTransfer
GetIsochResults | IssueIsochTransfer
GetTransferStatus | IsTransferComplete
IssueBulkTransfer | IssueVendorTransfer

  • The following table shows the pipe functions that open and close communication channels between a USBD and a USB device.
AbortPipeTransfers
ClosePipe
IsDefaultPipeHalted
IsPipeHalted
OpenPipe
ResetDefaultPipe
ResetPipe

  • The following table shows the frame functions that control how the USBD module packages data into frames for transmission on the bus.
GetFrameLength
GetFrameNumber
ReleaseFrameLengthControl
SetFrameLength
TakeFrameLengthControl

  • The following table shows device configuration functions for specific kinds of data transfers defined in the Universal Serial Bus Specification.
ClearFeature | SetDescriptor
GetDescriptor | SetFeature
GetInterface | SetInterface
GetStatus | SyncFrame

  • The following table shows miscellaneous functions for tasks related to interacting with USB implementation.
FindInterface | RegisterClientDriverId
GetDeviceInfo | RegisterClientSettings
GetUSBDVersion | RegisterNotificationRoutine
LoadGenericInterfaceDriver | TranslateStringDescr
OpenClientRegistryKey | UnRegisterNotificationRoutine


Required Entry Points for USB Device Drivers

All USB device drivers must expose certain entry points in their DLLs to interact properly with the USBD module. The following entry points not only enable the USBD module to connect a driver with its peripheral, but also enable a driver to create and manage any registry keys it may need:

  • USBDeviceAttach

    The USBD module calls this function when the USB device is connected to a host computer. The driver’s implementation of this function can decline to control the device, in which case the USBD module attempts to find another driver to handle the device. A driver rarely declines to control a device, though it might under certain conditions. For example, the driver might decline to control the device if the driver can determine from the device configuration block that the device is newer than the driver. By doing so, the driver indirectly gives a user an opportunity to enter the name of the correct USBD DLL if Windows CE cannot locate another driver for the device. For more information, see USB Device Driver Attach Processing.

  • USBInstallDriver

    This function, which is called the first time that the USB device driver is loaded, allows the driver to create any registry keys that it needs. For more information on the format of these keys and how they are used to load USBDs, see USB Device Driver Load Process.

  • USBUnInstallDriver

    This function is called when a user removes the driver from a Windows CE–based platform. It is responsible for removing all registry keys created by the driver’s USBInstallDriver function and for releasing any other resources held by the driver. For more information, see Removing USB Device Drivers.


Registry Keys for USB Device Drivers

Registry keys control how USB device drivers are loaded. When a USB device is attached, a USBD module loads the appropriate USBD to control that device, based on the device’s configuration and interface descriptor information. The USBD module locates the correct driver by using a set of registry keys, which track both the drivers and the devices. The registry keys are stored as subkeys of the HKEY_LOCAL_MACHINE\Drivers\USB\LoadClients\. registry key.

This loading method provides a flexible framework that allows drivers to be loaded in different contexts, depending on the range of devices that they are able to control. For example, OEMs may decide to include a generic class driver with their Windows CE–based platform that can control a broad range of USB devices. However, an IHV may have a driver for the a specific USB device within that class that is more efficient or works better than the generic class driver. In this case, the IHV’s driver could control a subset of the devices that the generic class driver controls, while allowing other devices to continue to be controlled by the generic driver. The structure of the LoadClients key defines a framework in which programmers can specify driver precedence in great detail. The following are examples of the contexts that can cause specific USB device drivers to be loaded:

  • To match every device connected to the bus. For example, a driver that displays an icon in the system’s taskbar can be loaded to control each USB device connected to the system. In this case, the driver could purposely fail the USBDeviceAttach call after obtaining the device information, in which case the USBD module would continue looking for a driver to control the device. Only one driver of this type may be registered in the system.
  • To match a vendor-specific identifier. This is used for USB devices that do not fall into any currently defined class, or to provide an enhanced driver for a particular IHV’s USB devices. It is not recommended for general-purpose drivers that may be able to control devices from multiple IHVs.
  • To control devices of a specific device class. For example, you could write a USB device driver to control all human interface device (HID) class devices. The USB Working Group has defined other device classes, including communications, audio, and mass storage.
  • To control each interface on a device. For example, a USB CD-ROM drive that has an audio interface, as is common with CD-ROM drives that can play audio CDs, could have separate drivers for each interface. This method is the best for loading USB device drivers because it allows compound devices that require multiple drivers to operate without additional reconfiguration.

The registry key for a USBD should either be part of an OEM’s platform .reg file or be created when a USB device driver is installed on a Windows CE–based platform. At installation time, the key can be created either by a setup application or by the driver’s USBInstallDriver function. USBInstallDriver should create the keys indirectly, by calling the RegisterClientSettings function, rather than by invoking the Windows CE registry APIs. Installation by USBInstallDriver occurs when an unrecognized USB device is connected to the bus and the USBD module queries a user for the name of the device driver DLL. The USBD module then loads the driver and calls its USBInstallDriver function.

Subkeys for each driver have the form Group1_ID\Group2_ID\Group3_ID\DriverName. Each of the group identifier subkeys can be named Default to indicate that the USBD should be loaded if the remaining group identifier subkey names match the USB device. Otherwise, the group identifier subkey names are formed from combinations of vendor, device class, and protocol information, separated by underscores. This information comes from the USB device descriptor. The following table shows the allowable combinations.

Group key
Allowable forms
Group1_ID DeviceVendorID,
DeviceVendorID_DeviceProductID,
DeviceVendorID_DeviceProductID_DeviceReleaseNumber
Group2_ID DeviceClassCode,
DeviceClassCode_DeviceSubclassCode,
DeviceClassCode_DeviceSubclassCode_DeviceProtocolCode
Group3_ID InterfaceClassCode,
InterfaceClassCode_InterfaceSubclassCode,
InterfaceClassCode_InterfaceSubclassCode_InterfaceProtocolCode

The following example shows the registry key setup for the sample mouse driver.

[HKEY_LOCAL_MACHINE\Drivers\USB\LoadClients]
  [Default]
    [Default]
      [3_1_2]
         [Generic_Sample_Mouse_Driver]
           “DLL”=“USBmouse.dll”

This example shows that the driver contained in Usbmouse.dll called Generic_Sample_Mouse_Driver is loaded by default for any interface on a USB device with an InterfaceClassCode of 3 (HID class), InterfaceSubclassCode of 1 (boot interface subclass), and InterfaceProtocolCode of 2 (mouse protocol). These values are defined in the USB HID specification.

The following example shows the settings for the sample HID driver.

[HKEY_LOCAL_MACHINE\Drivers\USB\LoadClients]
  [Default]
    [Default]
      [3]
         [Generic_Sample_Hid_Class_Driver]
           “DLL”=“USBHID.dll”

This example shows that the driver contained in Usbhid.dll is called Generic_Sample_Hid_Class_Driver and is loaded for any interface with an InterfaceClassCode of 3.

According to the precedence rules for loading USB device drivers, if the settings for both the sample mouse and the HID drivers are included in the registry, the HID driver is loaded first because it has the more general Group3_ID subkey.


USB Device Driver Load Process

The USBD module takes the following steps when loading drivers, stopping as soon as it finds a driver that accepts control of the device. The following rules describe the algorithm that the USBD module uses to search for USB device drivers. In the descriptions, GroupX_ID refers to a key with the specified group set to one of the forms described in Registry Keys for USB Device Drivers and the remaining groups set to Default. If multiple drivers are registered within the same group, the one that contains the simplest form is loaded first. For example, a driver specifying a Group1_ID with device class code only, such as Default\DeviceClass\Default, loads before a driver specifying a Group1_ID with device class and subclass code, such as Default\DeviceClass_Subclass\Default. This allows Windows CE to conserve resources by loading as few drivers as possible. This procedure takes the following steps:

  1. The USBD module searches for a subkey with the name Default\Default\Default. If present, the module loads the driver listed within the Default\Default\Default\DriverName\DLL subkey. A driver registered in this way is loaded for all USB devices connected to the system.
  2. The USBD module searches for a vendor-specific driver. Vendor-specific drivers are identified by searching for the most general Group1_ID subkey that matches the device descriptor information. The most general subkey is the one that has a matching Group1_ID subkey containing the simplest allowable form and Default for the Group2_ID and Group3_ID subkeys. If a matching subkey is found, the module loads the driver listed within the subkey’s DriverName\DLL subkey. For more information on allowable forms, see Registry Keys for USB Device Drivers.
  3. The USBD module searches for a device class-specific driver. Class-specific drivers are identified by searching for the most general Group2_ID subkey. If a matching subkey is found, the module loads the driver listed within the subkey’s DriverName\DLL subkey.

The searches in steps 1 through 3 may not yield a matching USBD to control the device as a whole; that is, the device may have multiple interfaces, but no driver identified in steps 1 through 3 may match all of the interfaces present on the device. If so, the USBD module takes the following steps to search for matching drivers for each interface present on the device, searching for the most general Group3_ID subkey. If the USBD module finds a matching subkey, it loads the driver listed within the subkey’s DriverName\DLL subkey.

Finally, if no appropriate USBD is located, the USBD module prompts a user to enter the name of a DLL containing the correct driver. The USBD module then loads the driver and calls the driver’s USBInstallDriver function. USBInstallDriver should create an appropriate subkey for the driver by calling the RegisterClientSettings function so that the next time that the USB device is attached, the USBD module can locate the correct driver without prompting a user.

In some cases it may be necessary to specify the precedence order to a greater level of detail; for example, combining a vendor and device class specifiers. In these cases, the GroupX_ID values may be combined to generate other combinations. The precedence for such combinations is as follows, in descending order:

  1. Group1_ID\Default\Default
  2. Group1_ID\Group2_ID\Default
  3. Default\Group2_ID\Default
  4. Group1_ID\Group2_ID\Group3_ID
  5. Group1_ID\Default\Group3_ID
  6. Default\Group2_ID\Group3_ID
  7. Default\Default\Group3_ID

If multiple drivers are registered at a particular precedence level, the USBD module loads the one with the most general form.


USB Device Driver Installation

The HKEY_LOCAL_MACHINE\Drivers\USB\LoadClients registry key must be set up correctly so that the USBD module can load the appropriate driver for a device when a device is attached to the bus. Each installed USB device driver must have a subkey within the LoadClients key for the USBD module to load it.

For a USB device driver supplied by an OEM, the OEM should configure the LoadClients registry key in a platform’s .reg file to include keys for the driver. For third-party peripherals, however, the driver does not have appropriate registry keys when it is first connected to the platform. In this case, the USBD module fails to locate an appropriate USB device driver when the peripheral is attached to the bus. The USBD module instead displays a dialog box prompting a user to enter the name of the appropriate USB device driver dynamic-link library (DLL). The USBD then loads the specified driver to control the peripheral and calls the driver’s USBInstallDriver function.

The USB device driver’s USBInstallDriver function sets up the driver’s subkey correctly within the LoadClients\ registry key so that the USBD module can load the driver the next time that the peripheral is attached to the bus. The driver does this by creating a USB_driver_SETTINGS structure and passing it to the RegisterClientSettings function. The format of the USB_DRIVER_SETTINGS structure parallels that of the LoadClients registry key. If all the fields in a group have USB_NO_INFO value, the corresponding GroupX_ID is set to Default in the registry. For example, the following example shows the USB_DRIVER_SETTINGS for the HID class sample driver.

USB_DRIVER_SETTINGS DriverSettings;
DriverSettings->dwVendorId          = USB_NO_INFO;
DriverSettings->dwProductId         = USB_NO_INFO;
DriverSettings->dwReleaseNumber     = USB_NO_INFO;

DriverSettings->dwDeviceClass       = USB_NO_INFO;
DriverSettings->dwDeviceSubClass    = USB_NO_INFO;
DriverSettings->dwDeviceProtocol    = USB_NO_INFO;

DriverSettings->dwInterfaceClass    = USB_DEVICE_CLASS_HUMAN_INTERFACE;
DriverSettings->dwInterfaceSubClass = USB_NO_INFO;
DriverSettings->dwInterfaceProtocol = USB_NO_INFO;

The following example shows how calling RegisterClientSettings with this DriverSettings structure is equivalent to having set up this registry key.

[HKEY_LOCAL_MACHINE\Drivers\USB\LoadClients]
  [Default]
    [Default]
      [3]
         [Generic_Sample_Hid_Class_Driver]
           “DLL”=“USBHID.dll”

In general, the client driver performs the following operations in USBInstallDriver:

  • Registers a unique client driver identifier string by calling the RegisterClientDriverId function.
  • Sets up the LoadClients registry key correctly by calling the RegisterClientDriverSettings function.
  • Creates any driver-specific registry keys under the registry key returned by the OpenClientRegistryKey function. This is optional because many client drivers may not have any driver-specific registry settings. The registry key for driver-specific settings is HKEY_LOCAL_MACHINE\Drivers\USB\ClientDrivers\Client Driver Id String.

This location for driver-specific keys may change in future versions of Windows CE, so USB device drivers should always use OpenClientRegistryKey to manipulate the settings, rather than opening the registry key directly.

After USBInstallDriver completes these actions, it returns control to the USBD module. The USBD module once again attempts to load a client driver for the device, using the algorithm described in USB Device Driver Load Process. At this time, the USBD module calls the USB device driver’s attach routine.


USB Device Driver Attach Processing

After the USBD module loads a USB device driver for a peripheral, it calls the driver’s USBDeviceAttach function. In this function, the driver performs the following operations:

  • Determines whether it can control the peripheral. If the driver can control the peripheral, it returns TRUE to accept control. Otherwise, the driver returns FALSE to decline control. In the latter case, the USBD module continues to search for other drivers to control the peripheral.
  • Loads additional USB device drivers for other interfaces that may be present on the peripheral by calling the LoadGenericInterfaceDriver function. If a USB device driver accepts control of a peripheral, the USBD module stops searching for drivers to control the peripheral. The driver that accepts control must then load any other USB device drivers for other interfaces present on the peripheral.
  • Registers a callback function that is called when the peripheral is disconnected from the bus. USB device drivers use the RegisterNotificationRoutine function to register callback functions.


Removing USB Device Drivers

During the USB Device Driver Attach Processing operation, the device driver registers a callback function. When a user detaches a peripheral from the bus, the USBD module calls the callback function within that device driver. This function is called with the USB_CLOSE_DEVICE code, which is the only device notification code defined in Windows CE 2.10.

The callback function also has the option of calling other functions in the USB device driver, such as USBUnInstallDriver. USBUnInstallDriver removes all registry keys created by the driver’s USBInstallDriver function and releases any other resources held by the driver. In this way a user can remove any old registry settings for a particular device when a new or updated driver for that device is available. In Windows CE 2.10, the USBD module never calls USBUnInstallDriver.


Sample USB Device Drivers

The Platform Builder contains source code for a sample driver for USB mouse devices and an HID class driver. The mouse driver uses interrupt-driven transfers. OEMs and IHVs are encouraged to use the source code for these sample drivers as the basis for other USB device drivers. In the sample, the registry keys are configured to load the drivers automatically; plugging in a mouse or keyboard loads these drivers. Because the HID class driver can control mouse devices, there is no reason to include the mouse driver DLL on platforms that support USB keyboard and mouse devices.

After the sample USB mouse driver is loaded and the USBD module calls the driver’s USBDeviceAttach function, the driver calls an initialize function that opens a pipe to the mouse device’s interrupt endpoint. It also starts a worker thread to handle interrupts. This thread enters a loop in which it submits interrupt transfers by calling the IssueInterruptTransfer function. After the transfer completes, the driver retrieves the mouse event data from the function’s lpvBuffer parameter. It then creates an appropriate mouse event to submit to the Windows CE input system.

There are a number of USB device classes that Microsoft does not currently supply sample drivers for. These include the audio device, storage device, communication device, physical interface device, and power device classes.


Sample HID Class Driver

The sample USB human interface device (HID) class driver supports input devices such as keyboards, mouse devices, joysticks, gamepads, steering wheels, and so on. In order to present applications with a consistent method of accessing those devices, the HID class driver uses Microsoft® DirectInput® technology. The HID class driver uses the USB interrupt transfer and control transfer functions to access USB input devices. It uses the stream interface functions to interact with the DirectInput subsystem.

In addition to sending input events from HID class devices to the DirectInput subsystem, the HID class driver also always generates ordinary keyboard and mouse events by using the keybd_event and mouse_event functions. This is not necessary for interacting with the DirectInput subsystem, but it does mean that if an application that is using the mouse or keyboard fails or stops responding, the use of those devices is still available to other applications.

The DirectInput subsystem in Windows CE uses I/O control codes to request various actions from the HID class driver. The HID class driver must support the following eight I/O control codes in its IOControl function:

I/O Control Code
Description
IOCTL_HID_ACQUIRE | Notifies the HID class driver that the DirectInput subsystem no longer wants to receive events connected to a handle that was previously obtained through use of the IOCTL_HID_SET_FORMAT control code.
IOCTL_HID_ATTACH | Notifies the HID class driver that an application needs to use a device.
IOCTL_HID_ENUM_DEVICES | Return a list of devices that the HID class driver is currently managing.
IOCTL_HID_ENUM_OBJECTS | Return the number of input sources, such as buttons, on the device.
IOCTL_HID_GET_INST_DATA | Returns data from the device to the DirectInput subsystem.
IOCTL_HID_POLL | Requests that the HID class driver poll the device to get the device’s status.
IOCTL_HID_SET_FORMAT | Sets the format of data that the HID class driver returns for a device to the DirectInput subsystem, and acquires the device for use by an application.
IOCTL_HID_TRANSFER_EVENT | Registers an event handle that the HID class driver can use to notify the DirectInput subsystem when the device generates data.

The implementation of the DirectInput subsystem for Windows CE is a subset of the full DirectInput technology defined for desktop versions of Windows. The following differences between these implementations affect the HID class driver:

  • Windows CE supports only foreground exclusive mode.
  • Attempting to enumerate the available HID class devices fails if there are no such devices connected to the Windows CE–based platform because the USB subsystem unloads the HID class driver when there are no HID class devices to control.


Testing USB Device Drivers

There is no extensive USB test suite for Windows CE at this time. The sample USB mouse and HID drivers, the USB CD-Changer device driver for the Auto PC, and the USB 8x930Ax peripheral kit and evaluation board from Intel Corporation can be used to assist in testing USB scenarios. These are the methods used at Microsoft to test the USB system software for Windows CE 2.10. Further details on testing a USB system and the device drivers on an OEM platform are available in the Platform Builder.


NDIS Network Drivers

The network driver interface specification (NDIS) is the mechanism by which Windows CE supports network connectivity. NDIS provides a pair of abstraction layers used to connect networking drivers to protocol stacks, such as the TCP/IP and Infrared Data Association (IrDA), and to network adapters, such as Ethernet cards. NDIS presents two sets of APIs for writers of network drivers: one set interfaces to the networking protocol stacks, and one set interfaces to network interface cards (NICs).

Windows CE versions 2.0 and later implement a subset of the NDIS 4.0 model used by Windows NT, enabling OEMs and independent hardware vendors (IHVs) to port existing Windows NT networking drivers to Windows CE. The full NDIS supports several types of network driver, but Windows CE versions 2.0 and later support only miniport drivers, and not monolithic or full NIC drivers. In addition, Ethernet and IrDA are the only NDIS media types supported in Windows CE 2.10.

The following illustration shows the relationships among protocol stacks, NDIS, NICs, and miniport drivers in Windows CE.

For miniport drivers, Windows CE is largely source-code-compatible with Windows NT. This means that, with a few exceptions, Windows CE and Windows NT support identical NDIS APIs. Consult the Windows NT Device Driver Kit for extended information on how to write a miniport driver. Because full documentation is available in the Windows NT Device Driver Kit, the documentation for the Windows CE Device Driver Kit does not discuss at length the process of writing miniport drivers. Miniport drivers are complex pieces of software, and for this reason Microsoft recommends that you adapt one of the sample miniport drivers or port an existing miniport driver from another operating system, such as Windows NT, rather than writing one from scratch.

The Windows CE Platform Builder includes the following sample miniport drivers:

  • Proxim wireless Ethernet PC Card.
  • FastIR, which uses the National Semiconductor PC87338 chipset.
  • NE2000-compatible network adapters for PCI, ISA, and PCMCIA buses.
  • IrSIR infrared serial port intermediate miniport driver.
  • Xircom CE 2 Ethernet PC Card.

For a complete list of the NDIS APIs supported on Windows CE, including information on the minor differences between the Windows CE API and its Windows NT counterpart, consult the Reference.


NDIS Support in Windows CE

Windows CE versions 2.0 and later support the following NDIS features:

  • A subset of the NDIS 4.0 API
  • Ethernet (802.3) and IrDA media types
  • Standard miniport drivers
  • A subset of intermediate miniport drivers

    Windows CE supports intermediate drivers that use NDIS to expose a miniport interface to overlying protocol stacks and a custom interface to underlying device drivers. An example of such a driver is the IrSIR driver for infrared serial ports. Intermediate miniport drivers, unlike standard miniport drivers, do not use NDIS functions to access NIC hardware. They use NDIS functions only to access the protocol stack that they are bound to.

  • Plug and Play loading of miniport drivers for PC Card–based NICs

Windows CE versions 2.0 and later do not support the following NDIS features:

  • Monolithic or full NIC drivers.
  • General direct memory access (DMA)

    Windows CE versions 2.0 and later do not support the NDIS functions related to DMA. However, developers can implement DMA code in their miniport driver for a specific combination of a Windows CE–based platform and an NIC. For more information, see Implementing DMA for NDIS Miniport Drivers.

  • Contiguous physical memory allocations

    Miniports for built-in NICs that require contiguous physical memory for DMA transfers can have a physical block of memory reserved for this purpose in an OEM’s device memory map.

  • Intermediate miniport drivers that expose both a miniport interface for use by overlying protocol stacks and a protocol interface for use by other, underlying miniport drivers
  • Wide area networking through NDIS

    Protocols such as Serial Line Internet Protocol (SLIP) and Point-to-Point Protocol (PPP) are implemented by libraries that directly connect the TCP/IP protocol stack to an underlying transport medium, such as the serial port driver.

  • PC Card attribute space

    Miniport drivers for PC Card–based NICs should use the PC Card Services library to access attributes and other tuples on the PC Card.

  • Multipacket Sends

    Multipacket sends are not supported in Windows CE version 2.12 and earlier.


Compiling a Miniport Driver for Windows CE

The source code for miniport drivers on Windows NT is largely compatible with Windows CE. As long as a miniport driver uses NDIS functions supported by Windows CE, the process of porting a miniport driver to Windows CE is straightforward.

The most significant difference between Windows CE and Windows NT is that Windows CE does not support .sys or .inf files. This reduces the complexity and size of the Windows CE loader. Therefore, a miniport driver for Windows CE is compiled as a DLL that exports the DriverEntry function. DriverEntry typically performs any general or platform-specific initializations. It also registers the miniport driver with the NDIS system by calling NdisMRegisterMiniport. DriverEntry must have the following prototype.

NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pRegistryPath);

For sample DriverEntry implementations, see the source code for the sample miniport drivers.

Because Windows CE does not support the Common Network .inf file format for installing a device driver, you must ensure that the proper registry keys are created for the miniport driver, typically through a setup application or through the driver’s Install_Driver function. For more information, see Registry Keys for Miniport Drivers.

As well as those general issues related to the structure of miniport drivers themselves, there are issues relating to pointers, as well. I/O port addresses for miniport drivers are 32-bit virtual addresses that are mapped to the miniport driver’s process address space. Do not cast I/O port addresses to non-32-bit types, such as USHORT.

A miniport driver should be installed in the \Windows directory on a target Windows CE–based platform. Miniport drivers need certain system DLLs in order to load and function correctly. Ethernet miniport drivers require the Ndis.dll, Arp.dll, and Dhcp.dll files. IrDA miniport drivers require the Ndis.dll and Irdastk.dll files. OEMs can omit some of these files if their platforms do not have the hardware used by a particular type of driver. For example, platforms without a built-in infrared port do not require Irdastk.dll.

Miniport drivers for PC Card–based NICs can be loaded and unloaded dynamically when the NICs are inserted or removed. This is because PC Cards are detected automatically by the Plug and Play support in Windows CE. However, other types of NIC hardware that cannot be detected automatically by Windows CE require that a platform be restarted after the miniport driver is installed in order for Windows CE to use the driver. After a platform is restarted, the NDIS component loads all drivers that have an HKEY_LOCAL_MACHINE\Comm\Miniport\Group value of NDIS listed in the registry.


Implementing DMA for NDIS Miniport Drivers

DMA is important for efficient networking because it enables the layers in the networking architecture to share data without first copying that data. Currently, Windows CE does not have any inherent DMA mechanisms; however, developers can implement equivalent functionality in their miniport drivers.

There are two categories of DMA: slave DMA and busmaster DMA. Slave DMA is appropriate for OEMs because it requires a block of memory that is pre-allocated in the device memory map of the Windows CE–based platform. Miniport drivers can map that block of physical memory to the driver’s virtual memory space, and then use the VirtualAlloc and VirtualCopy functions to move data in and out of that space. For an example of this type of DMA implementation for a Windows CE operating system for a Windows-based hardware development target platform, see the National Semiconductor IrDA sample driver.

Currently, no sample miniport driver implements busmaster DMA, which is a slightly more complex mechanism than slave DMA. To receive data, the driver allocates a shared memory block, transfers the data to buffers within that block, and uses NDIS functions to indicate that a packet has arrived. To send data, the driver uses the LockPages and UnlockPages functions to map the virtual memory to device memory, informs the NIC of the addresses of the data, and instructs the NIC to send the data. This method can be faster for larger data block sizes.


NDIS Protocol Binding

When a miniport driver is loaded, it must bind to an appropriate protocol stack. The binding process connects the driver to the protocol stack so that they can operate together. Protocol binding takes place through the NdisOpenAdapter and NdisCloseAdapter functions.

The TCP/IP protocol stack supports miniports for both built-in and PC Card–based Ethernet hardware. The TCP/IP protocol stack in Windows CE can bind to multiple miniport driver instances, enabling it to use multiple NICs. In Windows CE 2.10, the IrDA stack supports only a single built-in infrared port, which means that the IrDA stack binds to only a single miniport driver instance.

For PC Card–based NICs and miniport drivers, protocol binding or unbinding occurs when the NIC is inserted or removed. When the NIC is inserted into a PC Card socket, the Device Manager identifies the card, loads its driver, and binds it to a protocol stack after the driver initializes itself. When the NIC is removed from the PC Card socket, the Device Manager unbinds the miniport driver from the protocol stack, shuts down the driver, and unloads the driver’s DLL.

The particular miniport instances that protocol stacks bind to are stored in HKEY_LOCAL_MACHINE\Comm\Protocol\Linkage\ registry keys. For more information, see Registry Keys for Miniport Drivers.


NDIS Power Management

Power management for PC Card–based NICs is identical to power management for other PC Cards. The miniport driver performs the same power-cycle processing required of all PC Card device drivers; no additional processing is necessary. After power returns, the Device Manager calls the appropriate unbind and bind functions in the miniport driver.

For a miniport driver for a built-in NIC, the miniport driver’s reset function is called when power returns. Miniport drivers for IrDA must support the OID_IRDA_REACQUIRE_HW_RESOURCES and OID_IRDA_RELEASE_HW_RESOURCES messages to perform power management properly. A miniport for IrDA starts without any resources; when the first IrDA socket is created, the IrDA protocol stack acquires the miniport’s resources. When all IrDA sockets are closed, the protocol stack releases the resources. This ensures that the miniport driver and its NIC are not consuming power when the IrDA stack is not in use. For an example of how these object identifiers are implemented, see the FastIR sample miniport driver.

In some cases, miniport drivers may need to prevent a Windows CE–based platform from suspending—for example, due to lack of user input—while the driver is engaged in active operations. In such cases, the miniport driver can use the SystemIdleTimerReset function to prevent Windows CE from entering suspend mode. However, if the miniport driver is active because of a high-level protocol connection, such as an open TCP/IP socket, the miniport driver generally can let the upper-level protocol stack prevent Windows CE from shutting down. The upper-level protocol stacks ensure that the system does not shut down while there are open sockets because such connections do not survive a power cycle.


Registry Keys for Miniport Drivers

When a miniport driver is installed on a Windows CE–based platform, the setup application should create several registry keys to expose the miniport driver to Windows CE properly. Windows CE loads NDIS drivers listed within the HKEY_LOCAL_MACHINE\Comm\ key. Subkeys within this key are named for the corresponding miniport driver.

The following table shows the subkeys contained in each Miniport\ key.

Name
Type
Description
DisplayName | SZ | A user-friendly name for the driver.
Group | SZ | The literal string “NDIS”.
ImagePath | SZ | The name of the DLL containing the miniport driver.
Linkage\Route | SZ | A set of Miniport Instance keys separated by commas.

The value of the Linkage\Route key lists additional subkeys of the Comm\ key for each miniport instance. These subkeys in turn contain a set of keys that describes the parameters of that miniport instance. The following table shows the subkeys contained in each Miniport Instance key.

Name
Type
Description
DisplayName | SZ | A user-friendly description of the miniport instance.
Group | SZ | The literal value “NDIS”.
ImagePath | SZ | The name of the miniport driver’s DLL.
Parms | subkey | Subkeys for the miniport driver’s parameters.

The following table shows the subkeys contained in each Miniport Instance\PARMS key.

Name
Type
Description
BusNumber | DWORD | The bus number for the miniport instance.
BusType | DWORD | The bus type of the miniport instance.

BusNumber values range from 0 to one less than the number of buses on a Windows CE–based platform. Valid BusType values are declared in the _INTERFACE_TYPE enumeration in the Ceddk.h header file. Use the Miniport Instance\Parms key to store any miniport-specific values because this is the registry location accessed when miniport drivers call the NdisOpenConfiguration and NdisReadConfiguration functions.

The following example shows a set of registry keys for a miniport driver.

[HKEY_LOCAL_MACHINE\Comm]
  [NE2000]
    DisplayName="NE2000 Compatible Ethernet Driver"
    Group ="NDIS"
    ImagePath="NE2000.DLL"
    [Linkage]
      Route="NE20001, NE20002"
  [NE20001]
    DisplayName="NE2000 Compatible Ethernet Driver"
    Group="NDIS"
    ImagePath="NE2000.dll"
    [Parms]
      BusNumber=0
      BusType=8
      CardType=1
      InterruptNumber=03
      IOBaseAddress=0300
      Transceiver=3

PC Card miniport drivers also require an HKEY_LOCAL_MACHINE\Drivers\PCMCIA\Plug-and-Play ID\ registry key. This key enables the driver to load correctly when its NIC is inserted into a PC Card socket. The key typically is named for the Plug and Play identifier of the PC Card, but this is not a requirement. However, if the key is not named for the NIC’s Plug and Play identifier, the driver needs additional registry keys to enable the driver-detection algorithm of the Device Manager to load the driver. For more information on driver detection, see Drivers\PCMCIA\Detect.

The following table shows the subkeys contained in the HKEY_LOCAL_MACHINE\Drivers\PCMCIA\Plug-and-Play ID\ key.

Name
Type
Description
DLL | SZ | The literal string “Ndis.dll”.
Prefix | SZ | The literal string “NDS”.
Miniport | SZ | The name of the miniport driver for the PC Card, which corresponds to the name of the registry key within HKEY_LOCAL_MACHINE\Comm\ for the miniport driver.

The following example shows the additional keys that a PC Card network adapter could have.

[HKEY_LOCAL_MACHINE\Drivers\PCMCIA\NICs-R-Us Inc.-Super2000-E6FE]
  DLL="NDIS.DLL"
  Prefix= "NDS"
  Miniport="NE2000"

Ndis.dll sets values for the BusNumber and BusType keys for PC Card–based NICs. The BusNumber key contains the socket and function pair for the network adapter. The BusType key contains the value for the PC Card bus. Finally, if the card information structure (CIS) of the PC Card contains a network address value, Ndis.dll creates a \HKEY_LOCAL_MACHINE\Comm\Miniport Instance\Parms\NetworkAddress key to store the network address.

Protocol binding for miniport drivers for PC Card–based NICs occurs automatically when the driver is loaded. Protocol binding for miniport drivers for built-in NICs is controlled by the registry keys stored within HKEY_LOCAL_MACHINE\Comm\IrDA\Linkage\ and HKEY_LOCAL_MACHINE\Comm\Tcpip\Linkage\. Each of these Linkage\ keys should contain a single key called Bind. You can set the Bind key to a list of miniport instances that the corresponding protocol stack binds to. The following example shows the values that the registry could contain to enable the IrDA protocol stack to bind to the IrSIR miniport and the TCP/IP stack to bind to both the PPP and NE2000 miniports.

[HKEY_LOCAL_MACHINE\Comm]
  [IrDA\Linkage]
    Bind=multi_sz:"IrSir1"
  [Tcpip\Linkage]
    Bind=multi_sz: "PPP","NE20001"


Testing NDIS Miniport Drivers

The Windows CE Device Driver Test Kit for Windows CE versions 2.1 and 2.11 includes a tool called Ndistest to assist in testing NDIS Ethernet miniport drivers. The Test Kit does not include any tools for testing IrDA miniport drivers. The Ndistest tool is a special protocol driver that provides functionality and stress testing. Ndistest for Windows CE is based on the test tool for Windows NT, with the difference that the Windows CE test tool does not include a Graphics User Interface to configure and run the tests. Rather, Ndistest for Windows CE requires that a user manually edit configuration files and start the tests using a command line. Dual-computer testing for Windows CE runs against an Ndistest server running Windows NT.

Although the Device Driver Test Kit is part of the Windows CE Platform Builder, it was not present for Windows CE version 2.10. The Device Driver Test Kit for Windows CE version 2.10 is available on the Windows CE Web site at http://www.microsoft.com/windowsce/downloads/embedded/default.asp. The Ndistest tool from the Device Driver Test Kit for Windows CE version 2.1 works on both Windows CE versions 2.1 and 2.11.


Block Device Drivers

Block device drivers are for devices that allow data to be read or written only in blocks of a fixed size. Block devices do not allow individual bytes of data to be read or written. Block sizes tend to be one or a few kilobytes; some common sizes are 512 bytes, 1 KB, 2 KB, and 4 KB. Block devices are ideally suited to mass storage and persistent storage applications, such as disk and tape drives or non-volatile RAM disks.

The most common block devices used with Windows CE are those that use linear flash memory chips to implement persistent storage. The material in this section, however, applies to drivers for any type of block device. Some common types of block devices are hard disks and ATA-style flash ram disks in miniature card, PC Card, and compact flash card form factors. Block devices that conform to the industry standard ATA specification work with the Microsoft ATADisk driver included with Windows CE.

Block device drivers for Windows CE are typically implemented using the stream interface driver model. These drivers are managed by the Device Manager, and expose file I/O functions in order to interact with applications. The most important of those functions for block device drivers is the driver’s DSK_IOControl function, which handles all I/O requests to block devices. The specific I/O control codes for DSK_IOControl are the same ones that Windows CE uses to interact with the file allocation table (FAT) file system driver.

Block device drivers are not required to use the stream interface driver model. They can use the file system driver model if the device that they control is to be used for file storage. OEMs or independent hardware vendors (IHVs) may also use the file system driver model to implement other functionality, such as secure encrypted file systems or extended file system name spaces.


Block Device Drivers for Linear Flash Memory Devices

The first version of Windows CE was used solely on platforms with battery-backed RAM storage with a simple file system to manage the storage. However, Windows CE versions 2.10 and later are often used on embedded systems that require persistent storage and cannot depend on battery-backed RAM storage. As a solution, flash memory has been implemented because it is the industry standard for non-volatile storage in embedded applications.

The two leading types of flash memory architecture are Advanced Technology Attachment (ATA) flash and linear flash memory. Both conform to the industry standard PC Card form factor, and they can be used interchangeably in existing PC Card sockets. However, there are significant differences between the two architectures that affect their performance on Windows CE.

ATA cards emulate the behavior of an ATA-style hard drive by means of linear flash memory components and a special microcontroller chip, which performs hardware emulation of an ATA-style hard disk. An ATA card appears as an ordinary hard drive to an operating system. ATA-style hard disks are block devices, and thus ATA cards require block device drivers in order to work with Windows CE.

Linear flash memory takes its name from the fact that, unlike ATA-style flash, the individual storage locations form a contiguous range of memory addresses, each of which can be accessed directly. Thus, linear flash memory can be read directly as though it were RAM or ROM. However, linear flash memory can only be written to in blocks. Moreover, linear flash memory on Windows CE uses a software driver layer to emulate a disk drive; this eliminates the need for special controller hardware. Linear flash memory devices that operate in this block-oriented fashion use the driver layer to translate data to and from a block format that Windows CE can understand.

This driver layer is called the flash translation layer (FTL). The underlying data format used by FTL software has been adopted by the PC Card industry as an official data format. The FTL software component implemented on Windows CE is the TrueFFS driver from M-Systems, Inc. The TrueFFS driver, a stream interface driver, exposes standard Windows CE stream interface functions to the operating system. Currently, the TrueFFS driver can access only a DiskOnChip built-in device from M-System, Inc. Windows CE supports linear flash memory in several form factors: minicards, industry standard PC Cards, and built-in DiskOnChip devices.


Block Device Functionality

Block devices can be closely integrated with Windows CE, providing the following functionality:

  • Extension of the size of the Windows CE object store

    Block devices can extend the Windows CE object store beyond the size of the system’s physical RAM. Block devices appear as folders within Windows CE Explorer. Users can perform many ordinary operations on block devices, such as drag-and-drop operations. Users can also create and delete files and directories, retrieve file and directory information, and even reformat the devices. These operations are all transparent to a user, who does not need to know that the underlying device is not the same as the system’s physical RAM. Because block device drivers interface seamlessly with Windows CE, it is the operating system’s file system code that performs these operations on the block device for a user.

  • Storing both code and data

    Users can store both application code and data files on a block device. In Windows CE 2.10 and later, the operating system can use demand paging to load applications into memory, as needed. Versions of Windows CE prior to 2.10 did not load applications from external block devices, using this demand paging mechanism; instead, they loaded the entire application into RAM when it was launched.

  • Interoperability between operating systems

    Data on block devices such as linear flash memory cards transfers seamlessly between Windows CE, Windows 95, Windows NT, and MS-DOS. All these operating systems provide support for these block devices, using their own driver layers.

  • Registry storage

    Windows CE versions 2.10 and later can store registry data on block devices, although it cannot be accessed directly from those devices. Windows CE 2.10 introduced APIs for saving and loading registry information from block devices. Registry data must first be copied to the RAM-based registry before it can be used. For more information, see Persistent Registry Storage on Block Devices.

  • Database storage

    Databases on Windows CE, such as Contacts or Tasks, can be stored and used in place on block devices. Windows CE 2.10 supports new APIs for mounting database volumes from locations other than RAM and ROM. For more information, see Persistent Database Storage on Block Devices.


Limitations of Linear Flash Memory for Block Devices

Although linear flash memory technology is very commonly used to implement block devices, there are some limitations to the hardware:

  • Linear flash memory typically provides read-access times similar to ordinary DRAM but has slow write-access times and limited write-cycle lifetimes. Linear flash memory is therefore unsuitable as a replacement for true DRAM. Instead, linear flash memory is best suited for supplementary storage space, as a solid-state replacement for disk drives.
  • On Windows CE, new memory technology drivers (MTDs) cannot be added dynamically to support additional types of linear flash memory hardware. Only OEMs can add support for new types of linear flash memory hardware.
  • Windows CE does not inherently support resident flash arrays (RFAs) because there is no standard approach for handling tasks such as error correction, interleaving, and wear leveling. OEMs can add linear flash memory hardware directly to platforms, but they should investigate the feasibility of using a socketed form of linear flash memory, such as DiskOnChip.
  • The TrueFFS driver must be a stream interface driver.


System Architecture for Block Devices

As has been mentioned, device drivers for block devices are generally stream interface drivers, and the block devices appear as ordinary disk drives. Applications access files on a block device through standard file APIs—for example, CreateFile and ReadFile—called on the appropriate device file name, such as “DSK1:” or “DSK2:”.

The following illustration shows the flow of control from an application call to ReadFile to the actual read from various kinds of block devices, using linear flash memory hardware.

The application calls ReadFile, using a handle to a file stored in linear flash memory. The FAT file system, which is included with Windows CE, translates the read request to logical blocks. The FAT file system searches the buffer cache for the requested blocks. If these are not present, it issues an IOControl request to read bytes from the block device. The TrueFFS driver receives the IOControl request, then fulfills the request by accessing the linear flash memory block device through one of the socket layers.


Block Device File Systems

Windows CE implements a separate file system, the FAT file system, to support block devices. The FAT file system does not read or write to block devices directly; it uses underlying block device drivers for all access to block device hardware. The block device driver must present the block device to the FAT file system as a block-oriented device.

Block device drivers transparently emulate ordinary disk drives, so applications do not need to behave differently when reading and writing files to linear flash memory. FAT implements a logical file system and provides an abstraction between files in the application name space, such as \PC Card\Excel Docs\Expense report.pxl, and devices in the device name space, such as “DSK1:”. The block device driver is responsible for guaranteeing safe I/O operations even when interrupted by a power cycle. The FAT file system accesses the block device by calling the block device driver’s IOControl function with the appropriate I/O control codes.

OEMs can implement additional installable file systems. Any such file systems should interact with a block device driver in the same way as the FAT file system.


Loading and Unloading a File System

Block device drivers need to perform certain tasks to work correctly with Windows CE file systems. When the driver receives DISK_IOCTL_INITIALIZED in its DSK_IOControl function, it also receives a pointer to a POST_INIT_BUF structure. This structure lists the driver’s registry key, which the driver can use to retrieve the name of a file system driver. The driver must pass that name and a device-specific handle also present in the structure to the LoadFSD function. The Device Manager then loads the correct file system driver. The file system driver name should never be hard coded into a block device driver; it should always be retrieved from the registry. Hard coding the file system driver name means that your block device driver could stop working if later versions of Windows CE use different names for their file system drivers.

The block device driver should be prepared to accept I/O control requests as soon as it calls LoadFSD, even if LoadFSD has not yet returned. Because of the way the Device Manager implements LoadFSD, it is possible for the file system driver to be loaded and to issue a request to your block device driver before LoadFSD actually returns. It is also possible for LoadFSD to return successfully, even if there are subsequent errors initializing the file system driver. Presently, there are no mechanisms that the block device driver can use to detect such errors.

Windows CE versions 2.12 and earlier do not support multiple file system drivers acting on the same block device. If a Windows CE–based system has multiple file system drivers installed, the block device driver must determine which one to load during its processing of DISK_IOCTL_INITIALIZED. A block device driver can make only one successful call to LoadFSD; calling LoadFSD more than once causes unpredictable behavior.

The Device Manager unloads file system drivers at the time that a block device’s driver is deregistered by the DeregisterDevice function. Once the file system driver is loaded, the block device driver cannot force it to unload or unmount the block device from the system’s directory structure.

Because file systems are frequently unloaded just prior to system shutdown, block device drivers must ensure that all write operations to the block device are fully complete before the driver’s DSK_IOControl function returns. Failure to do so can cause corruption of files or directories.


Implementing a Block Device Driver

The following sections describe how to implement a block device driver for Windows CE. Block device drivers must export the stream interface functions, perform the correct startup sequence, support device detection, use the correct registry keys, properly respond to power cycles, and provide an Install_Driver function.


Block Device Driver Functions

As has been mentioned, the block device driver exposes standard stream interface functions common to all drivers controlled by the Device Manager. For information about these standard stream interface functions, see Required Entry Points for Stream Interface Driver DLLs. In addition to the common stream interface API, the block device driver must also expose the following more specialized functions:

  • MyDriverEntry

    An entry point function for the device driver DLL. After the Device Manager calls LoadLibrary to map the DLL, the system calls MyDriverEntry. This function performs any initialization tasks necessary for the block device driver. Upon successful return from MyDriverEntry, the Device Manager associates the driver’s stream interface functions with a special device file name so that applications can access the device. The first flash memory device is named “DSK1:”, the second “DSK2:”, and so on. DSK_ is the device file name prefix for all block device drivers.

  • MyDriverCallback

    The status callback function for notification of events from removable flash media cards. The block device driver registers this callback function with the PC Card Services driver.

  • MyDriverDetectdisk

    The entry point for the block device driver’s detection routine. MyDriverDetectdisk is a detection function for sockets that support hot insertion of block media. After the Device Manager loads the block device driver DLL, it calls this function to perform detection on the media. Detection typically takes place at cold start and warm start. However, for sockets that support hot insertion, detection occurs when a device is inserted into the socket.


Loading Block Device Drivers

Block device drivers are generally stream interface drivers, and are therefore loaded in the same way as stream interface drivers. OEMs who include block device drivers with their Windows CE–based platforms include keys in the platform’s \Drivers\Builtin\ registry key so that the Device Manager loads the block device driver when the platform starts. Third-party block device drivers for PC Card block devices or similar removable hardware uses the \Drivers\PCMCIA\ registry key so that the Device Manager loads the driver when the relevant block device is connected to the system.


Registry Keys for Block Device Drivers

The Device Manager uses and manages several registry keys under the HKEY_LOCAL_MACHINE\Drivers\ key to load, track, and unload linear block device drivers. Built-in devices, such as the DiskOnChip, rely on the registry settings to be present at startup time; therefore, these keys must be part of the default registry. However, you can install keys for removable block devices, such as linear flash memory PC Cards, upon first use of the device.


Registry Keys for PC Cards and Minicards

To detect removable block devices, the Device Manager initiates a detection sequence to determine the specific device type. A driver named MyDriver would use the following registry entries in Windows CE version 2.1 and later. The Device Manager requires these keys to initiate the detection sequence.

HKEY_LOCAL_MACHINE
    [Drivers]
        [PCMCIA]
            [MyDriver]
                SZ: Prefix = DSK
                SZ: Dll = MyDriver.DLL
                SZ: IOCTL = (DWORD)4
                SZ: FSD = FATFS.DLL
                SZ: Folder = My Folder

            [Detect]
                [20]
                    SZ: Dll = MyDriver.DLL
                    SZ: Entry = MyDriverDetectdisk

The value of the Folder key within the MyDriver key is optional. Its value determines the folder names associated with linear flash memory devices. The default name is Storage Card for the first device, Storage Card2 for the second, and so on. For example, if you use the value of the Folder key to change the folder name to My Folder, that is the name of the first device. The second folder is My Folder2,and so on.

The subkey 20 within the Detect key is provided only as an example; it can be any other number. Its value determines the order in which the Device Manager tries the driver’s MyDriverDetectdisk function relative to other drivers’ detection functions when attempting to identify an unknown type of PC Card.


Registry Keys for Built-In Block Devices

Built-in block devices, ones that are an integral part of a Windows CE–based platform, are recognized based on the HKEY_LOCAL_MACHINE\Drivers\BuiltIn\ registry key. A driver called MyDriver should use the following registry entries in Windows CE version 2.1 and later.

HKEY_LOCAL_MACHINE
    [Drivers]
        [BuiltIn]
            [MyDriver]
                SZ: Prefix = DSK
                SZ: Dll = MyDriver.DLL
                SZ: Index = DWORD:1
                SZ: Order = DWORD:1
                SZ: IOCTL = DWORD:4
                SZ: FSD = FATFS.DLL
                SZ: WindowBase = DWORD:D0000
                SZ: Folder = My Folder

If you are building a Windows CE operating system for a desktop Windows-based hardware development target platform, set the CEPC_DISKONCHIP environment variable to 1 prior to creation of the OS image. Otherwise, add the registry entries to one of your registry (.reg) files.

The value of the Folder key is optional. The value of the WindowBase key is provided only as an example; it can be any other 32-bit value, as specified in the documentation for your block device hardware. This value determines the location of the block device’s memory window.


Installing a Block Device Driver

If a user connects an unrecognized block device to a Windows CE–based platform, the Device Manager queries a user to locate the appropriate block device driver DLL. The Device Manager then calls that driver’s Install_Driver entry point. The Install_Driver function should ensure that any necessary data files are properly installed and create the relevant registry keys for the block device within the \Drivers\ portion of the registry. Block device drivers that are installed through other means, such as by an OEM as part of the software built into a Windows CE–based platform or remotely by the desktop Windows CE Services software, do not need to have an Install_Driver function.


Detecting a Block Device

At startup time or when a block device is connected to a Windows CE–based platform, the Device Manager calls the driver’s detection function, which is listed among the driver’s registry keys. The detection function attempts to recognize the type of block device hardware present by querying the device. If the driver recognizes the device, the Device Manager loads the block device driver into memory. This detection and load process is standard procedure, not only for block device drivers, but also for all stream interface drivers. For more information, see Device Manager.


Accessing a Block Device

There are two methods for accessing block devices, depending on whether the device is built into a Windows CE–based platform or whether the device is removable by a user.

Drivers for built-in block devices access their devices by mapping the device’s address space directly into the operating system’s address space. The driver should use the MMapIOSpace function to map the block device into system memory.

Block device drivers for removable block devices need to use a memory window to access their devices. The driver should use the VirtualAlloc and VirtualCopy functions to create the window, which the PC Card Services library can then use to read and write data between the driver and the block device.


IO Control Codes for Block Device Drivers

Block device drivers must respond to the following I/O control codes to interface properly with the FAT file system. For complete information on these codes, see the Reference.

I/O control code
Description
DISK_IOCTL_GETINFO | Retrieves information about the block device
DISK_IOCTL_READ | Reads data from the block device
DISK_IOCTL_WRITE | Writes data to the block device
DISK_IOCTL_SETINFO | Sets information about the block device
DISK_IOCTL_FORMAT_MEDIA | Formats at a low level or reformats the block device
DISK_IOCTL_GETNAME | Retrieves the name that file system drivers should use as the block device’s folder


Power-Cycle Processing by Block Device Drivers

The Windows CE power management protocol supports power cycles that are transparent to applications. Therefore, it is important that block device drivers handle the POWER_DOWN and POWER_UP system messages efficiently.

Like all device drivers, block device drivers must limit themselves to minimal, very fast processing of the POWER_DOWN message. To accomplish this, they should save any volatile state information in RAM, set a flag to indicate that power is about to be turned off, and exit. POWER_ON processing is exactly like the processing for a regular card removal that is followed by an insertion. When power resumes, the PC Card Socket driver issues a card-removal notification for all sockets with inserted cards. Next, it checks the socket status and issues card-insertion notices for each socket with a card. Finally, the Device Manager launches its detection sequence and loads the appropriate driver for each card.

Block device drivers must detect whether they are being loaded either in response to a POWER_ON message or because a block device was disconnected from, and then reconnected to the system. This is important because the driver should preserve state information for any handles held by applications to files stored in the linear flash memory device across simple power cycles. However, if the block device is removed and replaced with a different card, any open file handles should be closed.

The following table shows how open file handles should be treated during POWER_UP processing.

Transition
Preserve open file handles
Simple power cycle | Yes
Block device removed and subsequently re-inserted | Yes, if it is possible to detect that the contents of the device have not changed
Block device removed and replaced with a different device | No


Sample Block Device Drivers

The following sections describe the programming details of two sample block device drivers in Windows CE.


Sample ATADISK Driver

In addition to the standard stream device driver functions, the ATADISK driver also exports a PC Card Plug and Play detection function, DetectATADisk. The detection function only reads the attribute space of the PC card; no other data is read, and no write operations are performed on the PC card. The function looks for disk device type 4 in the PC Card’s CISTPL_FUNCID tuple and for ATA device type 1 in the type 1 CISTPL_FUNCE tuple.

The presence of the \Drivers\PCMCIA\ATADisk\ key causes the Device Manager to call the driver’s DetectATADisk function when a PC Card is inserted and there is no driver associated with the card’s Plug and Play ID. The following example shows how this takes place.

HKEY_LOCAL_MACHINE
    [Drivers]
        [PCMCIA]
            [Detect]
                [50]
                    SZ: Dll = ATADisk.DLL
                    SZ: Entry = DetectATADisk

When DetectATADisk detects an ATA-compatible PC Card, it causes the Device Manager to load the driver listed in the \Drivers\PCMCIA\AtaDisk\ registry key. The following example shows how this done.

HKEY_LOCAL_MACHINE
    [Drivers]
        [PCMCIA]
            [ATADISK]
                SZ: Prefix = DSK
                SZ: Dll = AtaDisk.DLL
                SZ: IOCTL = (DWORD)4
                SZ: FSD = FATFS.DLL

The four values shown are required.

The following values within the ATADISK key are optional. If present, these values affect all devices that the ATADISK driver operates on. Some of the following values are supported so that the ATADISK driver can work with some older ATA disk devices.

Folder
“Storage Card” causes ATADISK to report a default volume name of “Storage Card” in response to a DISK_IOCTL_GETNAME DeviceIOControl. You can use a different name than “Storage Card”, if desired.
Cylinders
xxx causes the ATADISK driver to not rely on the number of cylinders reported by the ATA device in response to the ATA IDENTIFY command. The number specified by the Cylinders registry value is used instead.
Heads
hh causes the ATADISK driver to not rely on the number of heads reported by the ATA device in response to the ATA IDENTIFY command. The number specified by the Heads registry value is used instead.
Sectors
ss causes the ATADISK driver to not rely on the number of sectors per track reported by the ATA device in response to the ATA IDENTIFY command. The number specified by the Sectors registry value is used instead.
CHSMode
1 forces the ATADISK driver to use Cylinder/Head/Sector (CHS) addressing mode. If the CHSMode value is 0 or the value is not present, the ATADISK driver uses the addressing mode reported by the ATA device in response to the ATA IDENTIFY command. The ATADISK driver uses Logical Block Address (LBA) mode, when available.


OEM Considerations for Linear Flash Memory

The following sections describe aspects of linear flash memory that OEMs should be aware of when implementing Windows CE–based platforms and block device drivers for those memory technologies. The sections include information on how an OEM can customize the TrueFFS driver on a Windows CE–based platform. These sections do not contain information for IHVs who want to create applications that use linear flash memory. For this type of information, see Programming Considerations for Linear Flash Memory.


TrueFFS Driver Customization

The Platform Builder contains a core library, Tffscore.lib, and a single source file, Flcustom.c, which together compose the TrueFFS driver. Flcustom.c contains translation layers, socket interfaces, and MTDs. All three of these components can be modified to conform to individual design features of a Windows CE–based platform.

However, to integrate any of these three components into the TrueFFS driver, the component’s registration routine must be called during initialization of the driver. This task is performed by the flRegisterComponents function, which is defined in Flcustom.c. Prototypes for all the components’ registration routines are provided in the Stdcomp.h header file.

OEMs can modify flRegisterComponents to include the desired subset of components for the application. The flRegisterComponents function takes no parameters and has no return value. It simply consists of calls to each component’s registration routine.

The following sections provide additional information about the components—MTDs, translation layers, and socket interfaces—and their registration routines.

Memory Technology Drivers
The TrueFFS driver accesses various types of linear flash memory hardware through MTDs. Each type of linear flash memory requires its own MTD because individual MTDs are tailored to interact with specific linear flash memory chips. For this reason, OEMs can omit any MTDs that are superflous. For example, if a platform supports only built-in DiskOnChip hardware, an OEM can omit the MTDs for Intel linear flash memory chips. By extension, however, OEMs who need to support new types of linear flash memory hardware must create MTDs for that hardware.

The following table shows existing MTDs and their corresponding registration routines.

Manufacturer
Product
Registration routine to be
called in Flcustom.c
M-Systems, Inc. | DiskOnChip | flRegisterDOC2000
Series 2000 | flRegisterCDSN
FlashLite (8-bit mode) | flRegisterI28F008
FlashLite (16-bit mode) | flRegisterI28F016
Intel | Series II (8-bit mode) | flRegisterI28F008
Series II (16-bit mode) | flRegisterI28F016
Series II+ | flRegisterI28F016
Series 100 MiniCard (8-bit mode) | flRegisterI28F008
Series 100 MiniCard (16-bit mode) | flRegisterI28F016
Series 200 MiniCard | flRegisterCFISCS
Value Series 100 (8-bit mode) | flRegisterI28F008
Value Series 100 (16-bit mode) | flRegisterI28F016
Value Series 200 (8-bit mode) | flRegisterCFISCS
Value Series 200 (16-bit mode) | flRegisterCFISCS

Translation Layers
Translation layers provide the necessary mapping between FAT file system data structures and the underlying data format on the linear flash memory hardware. The most widely known and used translation layer is the flash translation layer (FTL), a PC Card industry standard for NOR-based linear flash memory hardware. A separate implementation of the FTL for NAND-based linear flash memory is called the NFTL translation layer. DiskOnChip and other Series-2000 products are NAND-based products.

OEMs can omit unnecessary translation layers. For example, an OEM who wants to use only built-in DiskOnChip hardware can omit the FTL and keep the NTFL. However, TrueFFS supports storage of both FAT16 and FAT32 data structures.

The following table shows the registration routines of existing translation layers.

Registration routine
Hardware
flRegisterFTL | NOR-based linear flash memory hardware
flRegisterNFTL | NAND-based linear flash memory hardware

Socket Interfaces
Socket interface components control the access of the TrueFFS driver to sockets in which linear flash memory hardware resides. For PC Cards, the interface components consist of the PC Card socket API. For built-in DiskOnChip devices, the socket interface is a custom software component. An OEM who provides DiskOnChip hardware but not PC Card sockets needs only the DiskOnChip socket layer.

The following table shows the registration routines for existing socket layers.

Registration routine
Hardware
flRegisterFixedFlash | Built-in DiskOnChip hardware
flRegisterCS | PC Card–based linear flash memory hardware


Programming Considerations for Linear Flash Memory

The following sections describe programming aspects of linear flash memory performance on Windows CE that will be useful to most OEMs and IHVs. However, OEMs who want to customize the TrueFFS driver for a Windows CE–based platform should refer to OEM Considerations for Linear Flash Memory.


Writing a Linear Flash Memory Driver

Although Windows CE provides a linear flash memory driver in the form of the TrueFFS driver, OEMs or IHVs can write their own linear flash memory drivers on Windows CE, if desired.

In general, linear flash memory drivers are stream interface drivers; therefore, they expose stream interface functions common to all drivers controlled by the Device Manager. For more information about stream interface drivers and stream interface functions, see Developing Stream Interface Device Drivers.

DSK_IOControl is the main function in the stream interface group that handles all I/O requests. The I/O control codes themselves are the same as those used by the FAT file system. For details about the semantics of those codes, see the Windows CE Platform SDK.

A linear flash memory driver is not required to be a stream interface driver. An OEM can implement a custom driver—for example, a monolithic driver—that supports linear flash media as long as the driver fits the Windows CE–based device driver model.


Persistent Database Storage on Block Devices

Linear flash memory can store and update database information, including information contained in the Windows CE Contacts, Tasks, and Calendar databases. Windows CE 2.10 supports databases on any mounted file system, regardless of the file system’s storage mechanism. A new database API enables developers to create and mount an existing database volume—for example, the volume contained in the object store—on an external storage device, such as a linear flash memory card.

Operations on a new database volume are identical to operations on an object store database. A new database volume contains both the data and an integrity log that tracks changes for atomic operations. There are several database functions to facilitate these operations, such as the CeMountDBVol function, which is used to mount a database. There are also extended versions of existing functions, such as the CeOpenDatabaseEx function, which opens a database on a mounted volume. For full documentation on the database API, see the Windows CE Platform SDK.


Persistent Registry Storage on Block Devices

In addition to database information, linear flash memory cards can store registry information. However, Windows CE cannot use registry information stored in linear flash memory directly. The information must first be copied to the RAM-based registry.

Windows CE versions 2.0 and earlier implement the registry as a RAM-based heap file. However, this means that registry information is lost if power is lost to the platform’s RAM, a circumstance that forces Windows CE to reload the registry from ROM. Windows CE 2.10 provides new functions for saving and restoring registry information to and from any storage location, such as linear flash memory devices. The registry is saved to non-volatile linear flash memory when the platform is turned off and restored when power is restored. The RegCopyFile function saves registry information, and the RegRestoreFile function loads registry information. For full documentation on these two functions, see the Windows CE Platform SDK.

One solution for restoring registry information involves a dual-startup setup of the platform. In this case, the cold startup restores the registry, and a warm startup turns on the system. A warm startup maintains RAM, which means that the restored registry information is available to control the startup sequence. OEMs can provide a special registry cold-startup tool to copy saved registry information from linear flash memory into RAM after the Device Manager loads the TrueFFS. The utility then forces a warm startup of the system.

A single-startup solution is possible if the system uses the internal ROM file system code to restore the registry from its saved location. This is accomplished by using the WriteRegistryToOEM and ReadRegistryFromOEM functions in the platform’s OAL layer. Implementing these two functions can be complex because, at the time they are called, very little system support is present. The Device Manager has not yet been loaded, and no device drivers are available. Therefore, these functions need enough understanding of the external registry storage mechanism to locate and load the registry information without the help of the TrueFFS device driver. For full documentation of WriteRegistryToOEM and ReadRegistryFromOEM, see the Platform Builder.


Execute-in-Place Functionality

Execute-in-place (XIP) functionality is the ability to run an application directly from linear flash memory, instead of copying the application into RAM memory and running it from there. To support XIP, a device must be linear in nature, meaning it can be mapped into a memory window and read directly through the window as if the linear flash memory were RAM or ROM. Among linear flash memory devices, only NOR-based devices, such as minicards or resident flash arrays, can be used for XIP. NAND-based devices, such as DiskOnChip do not support XIP because they use complicated access methods to access memory cells within the device. For example, the electrical specifications of DiskOnChip match those of disk drives; disk drives are block devices, and therefore cannot be used to read individual addresses.

Implementing XIP from a built-in linear flash memory device does not require use of the TrueFFS driver. It is required only to install a file system on a linear flash memory device and access it as a random-access storage device. XIP does not need a file system; therefore, implementing XIP does not require use of the TrueFFS driver. An OEM can implement XIP if the target platform provides built-in linear flash memory, such as a resident flash array, or PC Card–based linear flash memory that can be mapped into the system’s address space.

OEMs should consider the following factors when implementing XIP from a linear flash memory device:

  • Windows CE 2.10 supports XIP from only one address space, the one in which the kernel itself runs. This is because Windows CE modifies the addresses of many system calls, thus enabling the calls to run in the context of the calling thread. Doing so has advantages for memory use, but it limits XIP to the virtual memory address space of the Windows CE kernel.
  • Because XIP occurs only in the kernel’s address space and Windows CE itself is executed in place, any linear flash memory that might be used for XIP must be built in, or it must be a linear flash memory device that is memory-mapped directly onto the kernel’s address space.

For additional information about implementation, see Starting Windows CE from Linear Flash Memory.


Partitioning Linear Flash Memory

OEMS have the option of configuring linear flash memory as either a single contiguous space or as multiple partitions, even though Windows CE currently supports only single partition. The following is information about partitioning a device for both single and multiple configurations:

  • Single partition

    An OEM can treat linear flash memory as a single contiguous address space. In this configuration, linear flash memory can be used either for XIP or for data storage. Data storage can include one or more of the following: a registry, a database, or user data files managed by the FAT file system.

  • Multiple partitions

    Windows CE 2.10 does not support multiple partitions at this time; however, multiple partitioning enables OEMs to logically divide linear flash memory into separate partitions. In a configuration known as Code Plus Data, one partition is used for XIP and another is used for data storage. Another configuration, known as Data Plus Data, divides linear flash memory into two data storage partitions: one partition provides data storage managed by the TrueFFS driver, and the other partition provides data storage managed by OEM-defined code.

  • Partitions on a DiskOnChip device

    OEMs who use the DiskOnChip device have the option of making the space on the device appear as separate partitions, although Windows CE 2.10 does not provide built-in support for multiple partitions on a single linear flash memory device. M-Systems, Inc., does offer a customization toolkit enabling OEMs to create a hidden data partition on the device. OEMs should contact M-Systems, Inc., for further assistance on how to access this hidden partition from within Windows CE.


Starting Windows CE from Linear Flash Memory

An OEM can use linear flash memory to store a Windows CE operating system image, making it possible to start Windows CE directly from a linear flash memory device, instead of from ROM. Starting the operating system image from linear flash memory mandates that the platform also support XIP because Windows CE itself runs in XIP mode. In turn, this means that startup is possible only on built-in linear flash memory that is mapped directly into the system’s main address space.

One method for implementing startup involves writing a separate startup-loader application that copies the image to the built-in linear flash memory device, and then executes that image. This method does not involve the use of the TrueFFS driver because the device is accessed directly from the startup-loader application. OEMs are free to implement their own startup solutions on linear flash memory devices. OEMs who want to implement startup from DiskOnChip through the use of the existing TrueFFS driver can contact M-Systems, Inc., for assistance.


Further Information on Using Linear Flash Memory with Windows CE

Consult the following sources for further information on using linear flash memory with Windows CE:

  • Windows CE Platform SDK

    Information on the FAT file system I/O control codes.

  • Windows CE Platform Builder version 2.11

    Information on building custom Windows CE operating systems and adapting Windows CE to custom hardware.

  • The M-Systems, Inc., Web site

    Details about linear flash memory technologies and software of M-Systems, Inc.

  • The Personal Computer Memory Card International Association (PCMCIA) Web site

    Information on the mechanical, electrical, and software specifications for PC Cards.


GPE Classes and Methods

This section is a reference to the device driver classes and interfaces, along with their methods, used on Windows CE.


GPE Base Classes

The Graphics Primitive Engine (GPE) consists of the following classes:

  • GPE
  • GPESurf
  • Node2D
  • ColorConverter
  • GPEVGA


GPE

This class serves as a base from which to implement individual display drivers. A GPE object represents a single display device.

The following code example shows the methods that a GPE-based driver must implement.

    // Configuration methods
    virtual SCODE    GetModeInfo(
                GPEMode *pMode,
                int modeNo )=0;
    virtual int    NumModes()=0;
    virtual SCODE    SetMode(
int modeId )=0;
    // Blit methods
    virtual SCODE    BltPrepare(
GPEBltParms *pBltParms )=0;
    virtual SCODE    BltComplete(
GPEBltParms *pBltParms )=0;
    // Line method
    virtual SCODE    Line(
                GPELineParms *pLineParms,
                EGPEPhase phase = gpeSingle )=0;
    // Surface creation method
    virtual SCODE    AllocSurface(
                GPESurf **ppSurf,
                int width,
                int height,
                EGPEFormat format,
                int surfaceFlags )=0;
    // Cursor methods
    virtual SCODE    SetPointerShape(
                GPESurf *pMask,
                GPESurf *pColorSurf,
                int xHot,
                int yHot,
                int cx,
                int cy )=0;
    virtual SCODE    MovePointer(
                int x,
                int y )=0;
    // Palette methods
    virtual SCODE    SetPalette(
                RGBQUAD *src,
                unsigned short firstEntry,
                unsigned short numEntries )=0;
    virtual SCODE    SetPalette(
                PALETTEENTRY *src,
                unsigned short firstEntry,
                unsigned short numEntries )=0;
    // Timing method
    virtual int    InVBlank()=0;


GPESurf

This class represents a surface allocated, either by the driver or by the Graphics Device Interface (GDI). The surface retains pixels in system memory or, if available on the Windows CE–based platform, in video memory.

Generally, this class is created for all surfaces when the driver allocates memory; for example, in response to the DrvCreateDeviceBitmap function. If the GDI allocates the surface, the driver creates a temporary surface of the TmpGPESurf class, which is derived from this class. This class is a wrapper around the SURFOBJ type created by the GPE. TmpGPESurf objects persist only for the duration of the call to the display driver.

This class provides a number of methods for a driver to retrieve pointers to pixel data, pixel format, stride, height, and width. In addition, GPESurf retains a flag to indicate whether the data is stored in video memory, which is verified by a call to the GPESurf::InVideoMemory method. The class also retains a flag that determines whether memory should be de-allocated when the GPESurf object is deleted.

Typically, you derive a new surface class based on the GPESurf class for video memory allocations.


Node2D

This class is a helper class for display devices that allocate memory as single rectangular blocks. For these types of device, the stride of bit block transfer (blit) operations is a constant, regardless of the width of the actual surface. Many devices, such as the S3Trio64 chipset, use the current screen width as the width of the video memory. All blit operations are assumed to have the same stride, or pitch, as the screen and the same pixel format.

To allocate a memory rectangle, create an initial Node2D object, using the same height and width as the memory block. Enter the width either in pixels or in bytes. Queries to allocated subrectangles of memory return the origin of the allocated memory in the same units with which the original Node2D object was created.

You must allocate subrectangles in the same units, as well. Allocate subrectangles using the Alloc method of the root node. Examine the origin of the new node, using the Top and Left methods of the node. As a final step, free the node, using the Free method. The following code example shows how the Free method is usually implemented.

// Assume there is a 640x1000-pixel line
// block of memory starting at memBase
// to be allocated as a rectangle.
#define MEM_WIDTH_IN_PIXELS 640
#define PIXEL_BYTES 2
#define MEM_HEIGHT 1000
extern unsigned char *memBase;
Node2D AllMem(MEM_WIDTH_IN_PIXELS, MEM_HEIGHT);
// Allocations are done in pixels.
// Create a 20x40 surface.
Node2D *pSurf1 = AllMem->Alloc( 20, 40 );
// Check that pSurf1 is not NULL.
// Create a 100x100 surface.
Node2D *pSurf2 = AllMem->Alloc( 100, 100 );
// Check that pSurf2 is not NULL.
int strideInBytes = MEM_WIDTH_IN_PIXELS * PIXEL_BYTES;
// Create a pointer the the top left of the block of
//    memory in surf1.
unsigned char *ptr1 = memBase + strideInBytes * pSurf1->Top()
+ PIXEL_BYTES * pSurf1->Left();
// Now delete the surface(s).
pSurf1->Free();
pSurf2->free();


ColorConverter

This class contains GPE color conversion support. The base ColorConverter class is defined in the Swconvrt.cpp file. This converter enables translation among any combination of source and destination surface pixel types at the time that bit blocks are written to the display.

Pixel formats for surfaces conform to one of the following types:

PAL_RGB
Format in which each pixel is an unsigned long of the form 0x00BBGGRR. This is identical to the PALETTENTRY structure.
PAL_BGR
Format in which each pixel is an unsigned long of the form 0x00RRGGBB. This is identical to the RGBQUAD structure.
PAL_MASKED
Format in which the red, green, and blue (RGB) channels of each pixel are isolated by using bitmasks to identify which specific bits are used for each channel. This is most common for formats of 15 and 16 bpp.
PAL_INDEXED
Format in which each pixel contains an index into the current palette for the surface. Palette entries may be 1, 2, 4, or 8 bits long, depending on how many bits per pixel the display uses.

When display drivers call GPE functions with XLATEOBJ pointer parameters, the functions create and initialize ColorConverter objects to handle any color conversion. Alternatively, based upon the value of the XLATEOBJ member iUniq, the functions may use a cached ColorConverter object from a previous call.

The ColorConverter object populates two pointers: pLookup and pConverter. If both are NULL, no conversion is required because the source and destination formats are compatible and palettes, if any, are identical.

If pLookup is not NULL, the operation must convert each source pixel to a destination pixel, using the source pixel value as an index into the lookup table. If pConverter is not NULL, it is the address of a function that is called to convert a source pixel to a destination pixel. Use this when source and destination formats are incompatible and the source format is not indexed. At most, either pLookup or pConverter is set to non-NULL.

Because color conversion is an optional feature for Windows CE, you can reduce or remove part or all of the feature in order to reduce the size of the driver. However, if you choose to alter the conversion feature, be sure to author all bitmaps provided for the platform to a bit depth or palette that is supported by the display driver. The current size of the complete color converter is slightly over 2 KB when compiled without debugging symbols.


GPEVGA

The GPEVGA class contains methods that simplify the process of using video chipsets that are compliant with the VGA standard. Many devices, such as the S3Trio64, are based on the VGA standard. For a VGA-based display driver, follow the S3Trio64 sample to implement the Gpevga.h header file and the functions define in the Gpevga.cpp file. This helps you configure the numerous VGA registers. If your device is not VGA-based, the GPEVGA class is not useful in developing your display driver.

Because the standard VGA registers do not include many of the high-resolution and high-bit-depth display modes, and because the registers do not define linear addressing schemes for display memory over 64 KB in size, you must determine the values to place in the non-standard registers, based on the characteristics of your display hardware. Keep in mind that GPE supports only those devices capable of presenting a linear frame buffer to the CPU.

To use the GPEVGA class, derive your specific device’s class from GPEVGA, rather than from GPE.


Initialization and Mode Setting

The GPE class includes the following methods for initialization and mode setting:

  • GPE::NumModes
  • GPE::GetModeInfo
  • GPE::SetMode


GPE::NumModes

This method returns the number of display modes supported by a driver. A simple implementation is to return 1.

Syntax

virtual int NumModes();

Return Values

Returns the number of display modes supported by a driver.


GPE::GetModeInfo

This method populates a GPEMode structure with data for the requested mode.

Syntax

virtual SCODE GetModeInfo( GPEMode *pMode, int modeNo );

Parameters

pMode
[OUT] Pointer to a GPEMode structure.
modeNo
[IN] Integer specifying the mode to return information about.

Remarks

The first mode is mode 0. The preferred mode for the device is mode 0.


GPE::SetMode

This method is called to enable the GPE-based device driver, if it is not already enabled, and to request a specific mode for the display.

Syntax

virtual SCODE SetMode( int modeID );

Parameters

modeID
Mode number to set.

Remarks

The modeID is the value from the modeID member of the GPEMode structure populated by a prior call to GPE::GetModeInfo. This can differ from the modeNo value used in the GetModeInfo call.

See Also

GPE::GetModeInfo


Surface Allocation

Display drivers allocate surfaces at initialization time for the video frame buffer, and possibly the cursor, when the GDI calls the DrvCreateDeviceBitmap function. GPE::AllocSurface, a required method, implements surface allocation within the driver.


GPE::AllocSurface

This method is called when the driver must allocate storage for surface pixels.

Syntax

SCODE GPE::AllocSurface( GPESurf **ppSurf, int width, int height, EGPEFormat format, int surfaceFlags );

Parameters

ppSurf
[OUT] Pointer to the memory allocated by the AllocSurface function.
width
[IN] Width, in pixels, of the surface to allocate.
height
[IN] Height, in pixels, of the surface to allocate.
format
Format of the surface.
surfaceFlags
[IN] One of the flags GPE_REQUIRE_VIDEO_MEMORY or GPE_PREFER_VIDEO_MEMORY, which specify where to allocate the memory

Return Values

If GPE_REQUIRE_VIDEO_MEMORY is set in the surfaceFlags parameter, the call returns one of two error values: if the available video memory is insufficient, the call returns E_NOT_ENOUGH_MEMORY, whereas if the allocation is inappropriate for video memory, such as an incorrect pixel format, the call returns E_INVALID_PARAMETER.

Remarks

For video memory allocation, the driver should implement a class, derived from GPESurf, that contains extra information, such as a pointer to the allocator used when freeing the memory. Refer to the Node2D class for information on a supplied memory allocator that can be used for rectangular allocation requirements.

The following code example shows the system memory allocation for this method.

    *ppSurf = new GPESurf( width, height, format );
    if( *ppSurf )
        return S_OK;
    return E_NOT_ENOUGH_MEMORY;

The surfaceFlags member can contain GPE_REQUIRE_VIDEO_MEMORY or GPE_PREFER_VIDEO_MEMORY, although neither is required. For GPE_PREFER_VIDEO_MEMORY, the driver should, if possible, allocate the surface from video memory. Otherwise, the driver should use system memory.


Blit Acceleration

Two blit-related pure virtual GPE functions must be implemented for concrete classes derived from GPE: GPE::BltPrepare and GPE::BltComplete.


GPE::BltPrepare

This method, which is called prior to a sequence of clipped blit operations, identifies the appropriate functions needed to perform individual blits.

Syntax

SCODE GPE::BltPrepare(GPEBltParms *pBltParms );

Parameters

pBltParms
Pointer to a GPEBltParms structure containing parameters for the blit operation.

Return Values

S_OK indicates success.

Remarks

The following code example shows the simplest acceptable implementation for GPE::BltPrepare.

pBltParms->pBlt = EmulatedBlt;
return S_OK;

This action causes the emulated blit function provided with GPE to be used for blit operations.

For improved performance, the BltPrepare method can examine the characteristics of the blit and the associated surfaces defined in GPEBltParms to determine whether an accelerated form of the blit is used. The following code example shows how to determine the operations that are likely to be implemented in hardware.

if( pBltParms->pDst->InVideoMemory() && pBltParms->rop4 == 0x0000 )
    // This is a fill of BLACKNESS in video memory.
if( pBltParms->pDst->InVideoMemory() && pBltParms->rop4 == 0xFFFF )
    // This is a fill of WHITENESS in video memory.
if( pBltParms->pDst->InVideoMemory()
&& pBltParms->rop4 == 0xF0F0
&& pBltParms->solidColor != 0xFFFFFFFF )
    // This is a fill of a solid color in video memory.
if( pBltParms->pDst->InVideoMemory()
&& pBltParms->pSrc->InVideoMemory()
&& pBltParms->rop4 == 0xCCCC
&& !pBltParms->pLookup
&& !pBltParms->pConvert )
    // This is a source copy (SRCCOPY) between two surfaces, both in
    // video memory, with no color translation.

To accelerate these types of blit, BltPrepare places the address of the accelerated function in the pBlt member of the GPEBltParms structure, instead of in the pointer to the EmulatedBlt function. For operations such as solid color fills, the driver can prepare the hardware. For example, the driver can place a solid color into the appropriate register of the hardware. This eliminates the need to repeat the same action in every call to the accelerated blit handler.


GPE::BltComplete

This class is called by GPE to complete a blit sequence initiated by GPE::BltPrepare.

Syntax

SCODE GPE::BltComplete( GPEBltParms *pBltParms );

Parameters

pBltParms
[IN] Pointer to a GPEBltParms structure containing parameters for the blit operation.

Remarks

This method can remove any hardware configuration established by GPE::BltPrepare prior to a blit sequence. Depending on your hardware, it might be unnecessary to remove some features, such as solid color settings. Other features may require removal so that certain accelerated operations perform correctly. For example, if clipping registers is set, they probably need resetting.


Line Acceleration

The only pure virtual line drawing method that must be overloaded in a GPE-based driver is GPE::Line.


GPE::Line

This method is called before and after a sequence of line segments, which are drawn as a path.

Syntax

SCODE GPE::Line( GPELineParms *pLineParms, EGPEPhase phase );

Parameters

pLineParms
[IN] Pointer to a GPELineParms structure containing parameters for the line.
phase
Phase of drawing for this call, either gpePrepare or gpeComplete.

Remarks

When called before a line sequence, the phase parameter has the value gpePrepare. Once the sequence is complete, the GDI calls this method with the value gpeComplete in the phase parameter.

The GPE::Line method examines the line parameters to determine whether the operation can be accelerated. It also places a pointer to a function to be called once per line segment into the pLine member of the GPELineParms structure. To use the emulated line drawing code supplied as part of the GPE, the following code should be executed.

pLineParms->pLine = EmulatedLine;
return S_OK;

If the pBltParms prclClip member is not NULL, the sequence of lines is clipped to a single clipped rectangle. If hardware acceleration of the line drawing is enabled and the hardware provides clipping registers, the driver prepares the clipping registers, and then places NULL in the pBltParms prclClip member. This ensures that the GPE does not attempt to clip the individual line segments.


Accelerated Line Segment Function

When an accelerated line draw function is implemented, it must draw lines with sub-pixel precision. The EmulatedLine function provided with the GPE performs the same task.

The function pointer in the pLineParms pLine parameter is called once for each line segment, with the start pixel on the destination surface defined by the pLineParms xStart and yStart parameters.

The Bresenham parameters for the line are passed in the pLineParms dM and dN parameters. The actual number of pixels to draw is indicated in the pLineParms cPels parameter.

The function should draw the line in an octant defined by the pLineParms iDir parameter, which contains values shown in the following illustration.


Cursor Display

Cursor display is optional. The requirements of the Windows CE–based target platform determine whether cursors are necessary. If the platform uses a stylus or a shell without a pointer, no cursor is necessary, and the GPE pointer methods can return S_OK without doing any work. Furthermore, it may be acceptable, depending on the target platform display hardware, to display only monochrome cursors.


GPE::SetPointerShape

This method sets the shape of the pointer, the hot spot of the pointer, and the colors to use for the cursor if the cursor is multicolored. The GDI calls GPE::MovePointer separately to move or hide the cursor.

Syntax

SCODE GPE::SetPointerShape( GPESurf *pMask, GPESurf *pColorSurf,
int xHot, int yHot, int cx, int cy );

Parameters

pMask
[IN] Pointer to a mask containing the cursor shape.
pColorSurf
[IN] Pointer to a surface specifying the colors to use for the cursor.
xHot
Horizontal location of the cursor’s hot spot.
yHot
Vertical location of the cursor’s hot spot.
cx
Width of the cursor.
cy
Height of the cursor.

Remarks

The pMask parameter points to a 1-bpp surface with a width of cx and a height of (2cy). The top half defines the AND mask for the pointer, and the lower half defines the XOR mask. Taken together, these masks provide 2 bits of information for each pixel of the pointer image. The following truth table shows display results for different values in the AND and XOR masks.

AND mask value
XOR mask value
Result displayed on screen
0 | 0 | Black.
0 | 1 | White.
1 | 0 | Transparent; pixel is unchanged.
1 | 1 | Inverts the pixel color.

These masks provide for a black-and-white image and enable transparency and inversion of pointer pixels.

If pColorSurf is not NULL, use the colors for the corresponding pixels of the color surface instead of the XOR mask value for pixels where the AND mask value is 0.


GPE::MovePointer

This method is called by applications either to move the hot spot of the cursor to a specific screen location or to hide the cursor.

Syntax

SCODE GPE::MovePointer( int x, int y );

Parameters

x
Horizontal screen location to move the cursor to. Applications can pass a value of –1 to hide the cursor.
y
Vertical screen location to move the cursor to.


Functions

This section is a reference to the device driver functions used on Windows CE.


AbortPipeTransfers

This function aborts all transfers on an open USB pipe.

Syntax

BOOL AbortPipeTransfers(USB_PIPE hPipe, DWORD dwFlags);

Parameters

hPipe
[IN] Handle to an open USB pipe.
dwFlags
[IN] Can contain either of the values USB_NO_WAIT or 0.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function blocks until all transfers have been successfully canceled on the endpoint unless USB_NO_WAIT is specified. If USB_NO_WAIT is specified, the transfers are flagged to be canceled, and this function returns immediately.

This function is defined in the Mousedrv.cpp file.


AbortTransfer

This function aborts an active transfer.

Syntax

BOOL AbortTransfer(USB_TRANSFER hTransfer, DWORD dwFlags);

Parameters

hTransfer
[IN] Handle to a USB transfer.
dwFlags
[IN] Either of the values USB_NO_WAIT or 0.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function halts a transfer in progress. It blocks the transfer until the transfer is successfully canceled unless USB_NO_WAIT is specified. If USB_NO_WAIT is specified, the transfer is flagged for cancelation, and this function returns immediately.

This function is defined in the Mousedrv.cpp file.


ACM_Close

This function closes an ACM device and its driver.

Syntax

BOOL ACM_Close(DWORD dwOpenData);

Parameters

dwOpenData
Specifies a value returned from a call to the ACM_Open function.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

The ACM Driver Wrapper library (Acmdwrap.lib) always returns TRUE for this function.


ACM_Deinit

This function deinitializes an ACM driver.

Syntax

PVOID ACM_Deinit(DWORD dwData);

Parameters

dwData
Specifies a value returned from a call to the ACM_Init function.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

The ACM Driver Wrapper library (Acmdwrap.lib) calls the DriverProc function with the DRV_FREE message.


ACM_Init

This function initializes an ACM driver.

Syntax

PVOID ACM_Init(DWORD dwInfo);

Parameters

dwInfo
Specifies information passed to the RegisterDevice function.

Return Values

Returns a DWORD, which is passed to the ACM_Open and ACM_Deinit functions, or NULL if unable to initialize the device.

Remarks

The ACM Driver Wrapper library (Acmdwrap.lib) calls the DriverProc function with the DRV_LOAD message.


ACM_IOControl

This function is the I/O control routine for an ACM device driver.

Syntax

BOOL ACM_IOControl(DWORD dwOpenData, DWORD dwCode,
PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
PDWORD pdwActualOut);

Parameters

dwOpenData
Specifies a value returned from a call to the ACM_Open function.
dwCode
Specifies an I/O control code for this function to perform. This function supports only one I/O control value, IOCTL_ACM_MESSAGE.
pBufIn
Pointer to the input parameter structure ACMDRV_MESSAGE_PARAMS.
dwLenIn
Specifies the size, in bytes, of ACMDRV_MESSAGE_PARAMS.
pBufOut
Pointer to the return value (DWORD).
dwLenOut
Specifies the size of the return value variable DWORD.
pdwActualOut
Not used, must be 0.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

The ACM Driver Wrapper library (Acmdwrap.lib) calls the DriverProc function with the message specified in the ACMDRV_MESSAGE_PARAMS structure.


ACM_Open

This function opens an ACM driver.

Syntax

PVOID ACM_Open(DWORD dwData, DWORD dwAccess,
DWORD dwShareMode);

Parameters

dwData
Specifies a value returned from a call to the ACM_Init function, which the driver is free to use or ignore.
dwAccess
Specifies a requested access level, a combination of GENERIC_READ and GENERIC_WRITE. The driver is free to use or ignore this value.
dwShareMode
Specifies a requested share mode, a combination of FILE_SHARE_READ and FILE_SHARE_WRITE. The driver is free to use or ignore this value.

Return Values

Returns a DWORD that is passed to the functions ACM_Read, ACM_Write, and so on, or NULL if unable to open the device.

Remarks

The ACM Driver Wrapper library (Acmdwrap.lib) always returns a constant value from this function.


ACM_PowerDown

This function turns an ACM device off.

Syntax

void ACM_PowerDown(void);

Remarks

This function is called to suspend the ACM device. No functions except those in the ACM driver’s DLL can be called from this function. The ACM Driver Wrapper library (Acmdwrap.lib) simply returns immediately. Hardware-assisted ACM drivers may need to implement some code in this function to properly shut down their hardware.


ACM_PowerUp

This function notifies an ACM device driver that the system is leaving the suspended state.

Syntax

void ACM_PowerUp(void);

Remarks

This function is called to restore a device from suspend mode. No functions except those in the DLL can be called from this function. The ACM Driver Wrapper library (Acmdwrap.lib) simply returns immediately. Hardware-assisted ACM drivers may need to implement some code in this function in order to properly turn their hardware on.


ACM_Read

This function reads from an ACM device.

Syntax

DWORD ACM_Read(DWORD dwOpenData, LPVOID pBuf, DWORD len);

Parameters

dwOpenData
The function is free to use or ignore this parameter.
pBuf
The function is free to use or ignore this parameter.
len
The function is free to use or ignore this parameter.

Return Values

The Wave API Manager never calls this function, so this routine may be empty and have an arbitrary return value. This is a required function for stream interface drivers, but the ACM_IOControl function handles all data communication. The ACM Driver Wrapper library (Acmdwrap.lib) always returns 0.


ACM_Seek

This function seeks for an ACM device.

Syntax

DWORD ACM_Seek(DWORD dwOpenData, long pos, DWORD type);

Parameters

dwOpenData
The function is free to use or ignore this parameter.
pos
The function is free to use or ignore this parameter.
type
The function is free to use or ignore this parameter.

Return Values

The Wave API Manager never calls this function, so this routine may be empty and have an arbitrary return value. This is a required stream interface driver function, but the ACM_IOControl function handles all data communication. The ACM Driver Wrapper library (Acmdwrap.lib) always returns –1.


ACM_Write

This function writes to an ACM device.

Syntax

DWORD ACM_Write(DWORD dwOpenData, LPCVOID pBuf,
DWORD len);

Parameters

dwOpenData
The function is free to use or ignore this parameter.
pBuf
The function is free to use or ignore this parameter.
len
The function is free to use or ignore this parameter.

Return Values

The Wave API Manager never calls this function, so this routine may be empty and have an arbitrary return value. This is a required stream interface driver function, but the ACM_IOControl function handles all data communication. The ACM Driver Wrapper library (Acmdwrap.lib) always returns 0.


ARGUMENT_PRESENT

This macro takes a parameter pointer and returns FALSE if the pointer is NULL, and TRUE otherwise.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

BOOLEAN ARGUMENT_PRESENT(IN (CHAR *) ArgumentPointer);

Parameters

ArgumentPointer
Specifies the value of the pointer argument to be tested.

Return Values

Returns FALSE if the value of ArgumentPointer is NULL, TRUE otherwise.

Remarks

This macro can be called in conditional code to determine whether an optional argument has been passed in a call.

A driver that calls this macro can be running at any IRQL.


ASSERT

This macro evaluates the specified condition in a debug build. If the resulting evaluations is FALSE, it calls the DbgAssert function to handle the assertion failure.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

ASSERT(Expression);

Parameters

Expression
Boolean that defines the condition to evaluate.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

If you use this macro, DbgAssert might display a message box. If this is not acceptable in your environment, use KASSERT instead.


ASSERTMSG

This macro evaluates the specified condition in a debug build. If the resulting evaluations is FALSE, it calls the DbgAssert function to handle the assertion failure and causes the message to be printed.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

ASSERTMSG(Message, Expression);


BatteryDrvrGetLevels

This function returns the number of levels that the battery driver is capable of returning in the BatteryFlag and BackupBatteryFlag members of the BATTERY_STATUS structure.

Syntax

LONG BatteryDrvrGetLevels(void);

Return Values

Contains the number of levels that the BatteryDrvrGetStatus function can return in the BatteryFlag member of BATTERY_STATUS. The low-order WORD contains the number of levels that can be returned for the main battery, and the high-order WORD contains the number of levels that can be returned for the backup battery.

The number of levels that can be returned ranges from 0 through 3. For example, if only the two values BATTERY_FLAG_HIGH and BATTERY_FLAG_LOW can be returned, the return value is 2. If BATTERY_FLAG_CRITICAL can also be returned, the value is 3.

Remarks

The BATTERY_FLAG_CHARGING, BATTERY_FLAG_NO_BATTERY, and BATTERY_FLAG_UNKNOWN values are ignored for the purposes of this count.

Implement this GWES function as part of porting native device drivers.

This function is declared in the Battery.h header file.


BatteryDrvrGetStatus

This function returns the status of the main and backup batteries.

Syntax

BOOL BatteryDrvrGetStatus(PSYSTEM_POWER_STATUS_EX2 pStatus,
PBOOL pfBatteriesChangedSinceLastCall);

Parameters

pStatus
Pointer to the return buffer containing the battery status information.
pfBatteriesChangedSinceLastCall
Pointer to a flag that the function sets to TRUE if the system's batteries have been replaced or changed since the last call to this function.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

Implement this GWES function as part of porting native device drivers. This function is declared in the Battery.h header file.

The syntax for this function is different in Windows CE version 2.12 than in previous versions of the operating system. This function now uses the SYSTEM_POWER_STATUS_EX2 structure, instead of the BATTERY_STATUS structure, to return the battery status. The new structure contains additional fields to support batteries that can report complex status information. If you are writing a battery driver for a previous version of Windows CE, you should use the following definition of the function BatteryDrvrGetStatus:

BOOL BatteryDrvrGetStatus(PBATTERY_STATUS pSystemPowerStatusEx);

Parameters

pSystemPowerStatusEx
Pointer to the buffer in which the battery status information is to be returned.

See Also

BATTERY_STATUS


BatteryDrvrSupportsChangeNotification

This function determines whether the battery driver can report when the batteries have been changed.

Syntax

BOOL BatteryDrvrSupportsChangeNotification(void);

Return Values

TRUE indicates that the battery driver supports notification. FALSE indicates that it does not.

Remarks

If FALSE, the fBatteriesChangedSinceLastCall member of the BATTERY_STATUS structure is always FALSE.

Implement this GWES function as part of porting native device drivers.

This function is declared in the Battery.h header file.


CardAccessConfigurationRegister

This function reads or writes the function and configuration registers of a PC Card.

Syntax

STATUS CardAccessConfigurationRegister(
CARD_CLIENT_HANDLE hCardClient, CARD_SOCKET_HANDLE
hSocket, UINT8 rw_flag, UINT8 offset, UINT8 *pValue);

Parameters

hCardClient
Specifies a client handle obtained from the CardRegisterClient function. If no other stream interface drivers own the configuration for the specified socket and function, a null value is permitted.
hSocket
Handle to the socket and function pair whose registers are to be accessed.
rw_flag
Specifies the operation to perform, either CARD_FCR_READ or CARD_FCR_WRITE.
offset
Specifies which register to access.
pValue
Pointer to the byte to write or to the location to store a byte when reading.

Return Values

CERR_SUCCESS indicates success. One of the following values indicates failure:

CERR_BAD_SOCKET
Indicates that the identifier specified for the hSocket member of the CARD_EVENT_MASK_PARMS structure is invalid or that there is no PC Card inserted in the socket.
CERR_BAD_HANDLE
Indicates that the driver handle specified for hCardClient is invalid.
CERR_BAD_OFFSET
Indicates that the value specified for offset is invalid.
CERR_IN_USE
Indicates that another stream interface driver owns the configuration for this socket and function.

Driver Name

PCMCIA


CardDeregisterClient

This function removes a stream interface driver’s registration from Card Services.

Syntax

STATUS CardDeregisterClient(CARD_CLIENT_HANDLE hCardClient);

Parameters

hCardClient
Client handle obtained from the CardRegisterClient function.

Return Values

CERR_SUCCESS indicates success. CERR_BAD_HANDLE indicates that the hCardClient driver handle is invalid.

Remarks

This function releases all PC Card Services resources that the driver has open, and turns off any PC Card sockets that contain unused PC Cards.

Driver Name

PCMCIA

See Also

CardRegisterClient


CardGetEventMask

This function retrieves either the driver’s global event mask or the event mask for a particular socket and function. The event mask specifies the events that trigger a callback.

Syntax

STATUS CardGetEventMask(CARD_CLIENT_HANDLE hCardClient PCARD_EVENT_MASK_PARMS pMaskParms);

Parameters

hCardClient
Client handle obtained from the CardRegisterClient function.
pMaskParms
Pointer to a CARD_EVENT_MASK_PARMS structure.

Return Values

CERR_SUCCESS indicates success. One of the following values indicates failure:

CERR_BAD_ARGS
Indicates that the pointer specified for pMaskParms is invalid.
CERR_BAD_HANDLE
Indicates that the driver handle specified for hCardClient is invalid.
CERR_BAD_SOCKET
Indicates that the identifier specified for the hSocket member of CARD_EVENT_MASK_PARMS is invalid or that no PC Card is inserted in the socket.

Remarks

If a stream interface driver used the CardRequestSocketMask function to associate a socket and function pair with an event mask, this function retrieves the event mask for the specified socket and function; otherwise, it retrieves the global event mask as set initially by CardRegisterClient.

This function returns the current event mask in the fEventMask member of CARD_EVENT_MASK_PARMS. If this function returns a global event mask, it ignores the structure’s socket identifier member hSocket.

Driver Name

PCMCIA

See Also

CARD_EVENT_MASK_PARMS, CardRequestSocketMask, CardSetEventMask


CardGetFirstTuple

This function retrieves the first tuple of the specified type for the specified socket and function.

Syntax

STATUS CardGetFirstTuple(PCARD_TUPLE_PARMS pGetTupleParms);

Parameters

pGetTupleParms
Pointer to a CARD_TUPLE_PARMS structure.

Return Values

CERR_SUCCESS indicates success. One of the following values indicates failure:

CERR_BAD_ARGS
Indicates that the pointer specified for pGetTupleParms is invalid.
CERR_BAD_SOCKET
Indicates that the socket identifier specified for the hSocket member of CARD_TUPLE_PARMS is invalid or that there is no PC Card inserted in the socket.
CERR_NO_MORE_ITEMS
Indicates that the end of the CIS was reached or that the requested tuple was not found.
CERR_OUT_OF_RESOURCE
Indicates that Card Services was unable to set up a memory window to read the CIS.
CERR_READ_FAILURE
Indicates that no PC Card is inserted or that the PC Card is unreadable.

Remarks

This function searches the CIS tuple chain in the PC Card’s attribute memory for the tuple specified by the uDesiredTuple member of CARD_TUPLE_PARMS. A uDesiredTuple value of 0xFF indicates that all tuples are returned. The driver retains the values returned in the uLinkOffset, uCISOffset, and fFlags members of CARD_TUPLE_PARMS so that subsequent calls to the CardGetNextTuple or CardGetTupleData functons follow the tuple chain. The uTupleCode and uTupleLink members are ignored when the return value is not CERR_SUCCESS.

To obtain tuple data, call CardGetTupleData.

CARD_TUPLE_PARMS and the CARD_DATA_PARMS structure are arranged so that their corresponding members are aligned. With care, a single buffer can be used in all calls to the Card Services tuple functions. This function turns on the PC Card socket if it is not on. The socket is turned off if no drivers have any memory windows open on the PC Card.

Driver Name

PCMCIA

See Also

CARD_DATA_PARMS, CARD_TUPLE_PARMS, CardGetNextTuple, CardGetTupleData


CardGetNextTuple

This function retrieves the next tuple of the specified type for the specified socket and function.

Syntax

STATUS CardGetNextTuple(PCARD_TUPLE_PARMS pGetTupleParms);

Parameters

pGetTupleParms
Pointer to a CARD_TUPLE_PARMS structure.

Return Values

CERR_SUCCESS indicates success. One of the following values indicates failure:

CERR_BAD_ARGS
Indicates that the pointer specified for pGetTupleParms is invalid.
CERR_BAD_SOCKET
Indicates that the hSocket socket identifier in CARD_TUPLE_PARMS is invalid or that no PC Card is inserted in the socket.
CERR_NO_MORE_ITEMS
Indicates that the end of CIS has been reached or that the requested tuple was not found.
CERR_OUT_OF_RESOURCE
Indicates that Card Services is unable to set up a memory window to read the CIS.
CERR_READ_FAILURE
Indicates that no PC Card is inserted or that the PC Card is unreadable.

Remarks

This function follows the CIS tuple chain, as specified by the uLinkOffset, uCISOffset, and fFlags members of CARD_TUPLE_PARMS. These members were set by a previous call to the CardGetFirstTuple function or this function.

To obtain tuple data, use CardGetTupleData.

The driver retains the values returned in the uLinkOffset, uCISOffset, and fFlags members of CARD_TUPLE_PARMS so that subsequent calls to this function or CardGetTupleData can follow the tuple chain. The driver does not access the uTupleCode and uTupleLink members unless the return value is CERR_SUCCESS.

The CARD_TUPLE_PARMS and CARD_DATA_PARMS structures are arranged so that their corresponding members are aligned. With care, drivers can use a single buffer in all calls to the Card Services tuple functions.

Driver Name

PCMCIA

See Also

CARD_DATA_PARMS, CARD_TUPLE_PARMS, CardGetFirstTuple, CardGetTupleData


CardGetParsedTuple

This function reads and decodes the CISTPL_CONFIG and CISTPL_CFTABLE_ENTRY tuples. These tuples are both complex and difficult to decode; this function stores the information in those tuples in data structures that are easier to access.

Syntax

STATUS CardGetParsedTuple(CARD_SOCKET_HANDLE hSocket
UINT8 uDesiredTuple PVOID pBuf PUINT32 pnItems);

Parameters

hSocket
Handle to a socket and function pair.
uDesiredTuple
Specifies the desired tuple to parse. Currently, only the CISTPL_CONFIG or CISTPL_CFTABLE_ENTRY tuples are supported for parsing.
pBuf
Pointer to the buffer to contain the parsed tuple information. Points to the PARSED_CONFIG or the PARSED_CFTABLE structure.
pnItems
Pointer, on entry, to the number of entries in the buffer pointed to by pBuf. On exit, this parameter specifies how many entries of pBuf are needed to store the results or how many entries are required if the buffer is not large enough.

Return Values

CERR_SUCCESS indicates success. One of the following values indicates failure:

CERR_BAD_ARG_LENGTH
Indicates that the buffer specified by the pnItems pointer is not large enough.
CERR_BAD_ARGS
Indicates that the pointer specified by pBuf is invalid.
CERR_BAD_SOCKET
Indicates that an hSocket socket identifier is invalid or that a PC Card is not inserted.
CERR_NO_MORE_ITEMS
Indicates that the end of CIS is reached or that the requested tuple is not found.
CERR_OUT_OF_RESOURCE
Indicates that Card Services is unable to set up a memory window to read the CIS.
CERR_READ_FAILURE
Indicates that no PC Card is inserted or that the PC Card is unreadable.

Remarks

This function reads the CIS data from the specified PC Card of the specified tuple code and formats the encoded data into an easily accessed structure. This function reduces code size by eliminating extra processing required to parse some variable-length tuples, thus duplication of code to process these tuples.

Currently, Windows CE supports only the CISTPL_CONFIG and CISTPL_CFTABLE_ENTRY tuples for parsing.

When this function is called with CISTPL_CONFIG, it retrieves a PARSED_CONFIG structure. When it is called with CISTPL_CFTABLE_ENTRY, it retrieves a PARSED_CFTABLE structure. Therefore, the pBuf pointer points to either PARSED_CONFIG or PARSED_CFTABLE.

If there are multiple CISTPL_CFTABLE_ENTRY tuples, this function retrieves the required number of PARSED_CFTABLE structures, provided the user’s buffer is large enough.

Driver Name

PCMCIA

See Also

PARSED_CONFIG, PARSED_CFTABLE, POWER_DESCR


CardGetStatus

This function retrieves the current status of the specified socket and function pair.

Syntax

STATUS CardGetStatus(PCARD_STATUS pStatus);

Parameters

pStatus
Pointer to a CARD_STATUS structure used to return the status information.

Return Values

CERR_SUCCESS indicates success. If the CARD_STATUS structure referenced by the pStatus parameter contains invalid information in its hSocket member, this function returns CERR_BAD_SOCKET. If the pStatus parameter itself is invalid, this function returns CERR_BAD_ARGS.

Remarks

The status is any of the event masks defined in the Cardserv.h header file, such as write protect, card lock, and battery dead. You can determine the status from the bit mask values this function retrieves in CARD_STATUS.

Driver Name

PCMCIA

See Also

CARD_STATUS


CardGetTupleData

This function reads the data from the current tuple.

Syntax

STATUS CardGetTupleData(PCARD_DATA_PARMS pTupleDataParms);

Parameters

pTupleDataParms
Pointer to a CARD_DATA_PARMS structure used to return the tuple data.

Return Values

CERR_SUCCESS indicates success. One of the following values indicates failure:

CERR_BAD_ARG_LENGTH
Indicates that the buffer specified by uBufLen in CARD_DATA_PARMS is not large enough.
CERR_BAD_ARGS
Indicates that the pointer specified by pTupleDataParms is invalid.
CERR_BAD_SOCKET
Indicates that an hSocket socket identifier in the CARD_TUPLE_PARMS structure is invalid or that a PC Card is not inserted.
CERR_NO_MORE_ITEMS
Indicates that the end of CIS has been reached or that the requested tuple was not found.
CERR_OUT_OF_RESOURCE
Indicates that Card Services is unable to set up a memory window to read the CIS.
CERR_READ_FAILURE
Indicates that no PC Card is inserted or that the PC Card is unreadable.

Remarks

This function returns data from the tuple specified by the fFlags, uLinkOffset, and uCISOffset members in CARD_DATA_PARMS. The driver maintains these member values whenever the CardGetFirstTuple and CardGetNextTuple functions are called.

Driver Name

PCMCIA

See Also

CARD_DATA_PARMS, CARD_TUPLE_PARMS, CardGetFirstTuple, CardGetNextTuple


CardMapWindow

This function maps an area in PC Card memory or I/O space to system memory and returns a pointer used to access the mapped region.

Syntax

PVOID CardMapWindow(CARD_WINDOW_HANDLE hCardWindow UINT32 uCardAddress UINT32 uSize PUINT32 pGranularity);

Parameters

hCardWindow
Handle to a memory window returned by a call to the CardRequestWindow function.
uCardAddress
Specifies a PC Card offset address.
uSize
Specifies the number of bytes to map.
pGranularity
Must be NULL.

Return Values

A PVOID pointer mapped to the requested region indicates success. NULL indicates failure, and GetLastError returns one of the following values:

CERR_BAD_ARGS
Indicates that a uCardAddress specification or pGranularity pointer is invalid.
CERR_BAD_HANDLE
Indicates that an hCardWindow driver handle is invalid.
CERR_BAD_SIZE
Indicates that the value specified for uSize is invalid.
CERR_OUT_OF_RESOURCE
Indicates that Card Services is unable to set up a memory window to read the CIS.

Remarks

If this function fails, a previous mapping of the window might be invalid.

The offset from the returned mapped virtual address must be multiplied by the value pointed to by pGranularity.

The pointer returned by this function can be used to access the PC Card directly. Drivers should access the memory in a try/except routine to avoid faulting the system on card removal.

The pointer to the mapped PC Card memory that this function returns is to non-cached shared memory. This function calls the VirtualAlloc function with flags to allocate non-cached memory. This guarantees that a PC Card device and its driver detect the same information when they access the same memory location.

To provide reliable access to the mapped PC Card memory, driver code should declare the pointer to the PC Card memory with the volatile type qualifier.

Most Windows CE–based platforms use three fixed memory-mapped ranges to access the PC Card address spaces: attribute memory, I/O memory, and common memory. The address returned from this function is a virtual address mapped to the physical address corresponding to the caller’s request. This function prevents multiple drivers from allocating overlapping ranges within each address space, though multiple allocations are permitted within each space. A single driver is enabled to map a range that overlaps its own previously allocated ranges.

Designers of Windows CE–based platforms that support programmable windows through a standard PC Card socket controller can define a combination of fixed memory-mapped ranges and programmable ranges in their Pcmcia.pdd file. If the requested range cannot be mapped within one of the fixed regions, one of the programmable regions can be used. To avoid memory contention, Windows CE ensures that only one mapped range exists within a programmable range. The programmable ranges are not large, about 32 KB, but they can access any 32 KB range within the 64 MB PC Card address space.

Driver Name

PCMCIA

See Also

CARD_WINDOW_HANDLE, CardRequestWindow


CardModifyWindow

This function changes the attributes of a memory window opened by the CardRequestWindow function.

Syntax

STATUS CardModifyWindow(CARD_WINDOW_HANDLE hCardWindow UINT16 fAttributes UINT8 fAccessSpeed);

Parameters

hCardWindow
Handle to a memory window returned by CardRequestWindow.
fAttributes
Specifies a bit-encoded window attributes mask.
fAccessSpeed
Specifies a bit-encoded access speed mask.

Return Values

CERR_SUCCESS indicates success. One of the following values indicates failure:

CERR_BAD_ARGS
Indicates that a value for fAttributes or fAccessSpeed is invalid.
CERR_BAD_HANDLE
Indicates that a driver handle specified for hCardWindow is invalid.

Driver Name

PCMCIA

See Also

CARD_WINDOW_HANDLE, CardMapWindow


CardRegisterClient

This function registers a callback function that is called by Card Services when a specified socket event occurs. The callback function notifies the driver of the event, such as card insertion, so that the driver can take the appropriate action.

Syntax

CARD_CLIENT_HANDLE CardRegisterClient(
CLIENT_CALLBACK CallBackFn PCARD_REGISTER_PARMS pParms);

Parameters

CallBackFn
Pointer to the driver’s callback function.
pParms
Pointer to a CARD_REGISTER_PARMS structure defining the driver’s characteristics.

Return Values

A driver handle indicates success. NULL indicates failure, and GetLastError returns one of the following values:

CERR_BAD_ARGS
Indicates that the pointer specified in pParms or CallBackFn is invalid.
CERR_OUT_OF_RESOURCE
Indicates that Card Services is unable to allocate memory to track the driver.

Remarks

This function turns on power to any unpowered sockets containing PC Cards so that the cards can be used by the newly registered PC Card driver. A driver can request artificial insertion notifications to check if a card that it controls has already been inserted.

Card Services sends a CE_CARD_INSERTION callback event code for every function on PC Cards that are currently inserted. If the driver does not require artificial insertion notices, it can clear the CLIENT_ATTR_NOTIFY_SHARED and CLIENT_ATTR_NOTIFY_EXCLUSIVE bits in the fAttributes member of CARD_REGISTER_PARMS.

Because the CE_CARD_INSERTION callbacks can occur before this function returns, the Parm2 member of the CARD_EVENT_PARMS structure contains the registering client’s CARD_CLIENT_HANDLE. For the same reason, Parm1 also contains the registering client’s handle on the CE_REGISTRATION_COMPLETE callback.

When the driver is unloaded, it must call CardDeregisterClient to free any PC Card resources allocated to the driver.

Driver Name

PCMCIA

See Also

CARD_CLIENT_HANDLE, CARD_EVENT, CARD_REGISTER_PARMS, CARD_EVENT_PARMS, CardDeregisterClient


CardReleaseConfiguration

This function places the selected socket and card into a memory-only interface, which is the default mode.

Syntax

STATUS CardReleaseConfiguration(CARD_CLIENT_HANDLE hCardClient CARD_SOCKET_HANDLE hSock);

Parameters

hCardClient
Handle obtained from the CardRegisterClient function.
hSock
Handle to a socket and function pair.

Return Values

CERR_SUCCESS indicates success. One of the following values indicates failure:

CERR_BAD_HANDLE
Indicates that the driver handle specified for hCardClient is invalid.
CERR_BAD_SOCKET
Indicates that the socket identifier specified for hSock is invalid or that a PC Card is not inserted.
CERR_IN_USE
Indicates that the configuration is owned by another driver.
CERR_WRITE_FAILURE
Indicates that this function is unable to write configuration registers.

Remarks

Card Services removes power if no other drivers are using the card.

Driver Name

PCMCIA

See Also

CardRequestConfiguration


CardReleaseExclusive

This function releases exclusive access to a socket and function pair.

Syntax

STATUS CardReleaseExclusive(CARD_CLIENT_HANDLE hCardClient CARD_SOCKET_HANDLE hSocket);

Parameters

hCardClient
Client handle obtained from the CardRegisterClient function.
hSocket
Handle to a socket and function pair.

Return Values

CERR_SUCCESS indicates success. One of the following values indicates failure:

CERR_BAD_HANDLE
Indicates that the driver handle specified for hCardClient is invalid.
CERR_BAD_SOCKET
Indicates that the socket identifier specified for hSocket is invalid or a that a PC Card is not inserted.
CERR_IN_USE
Indicates that exclusive use is owned by another driver.

Remarks

Card Services informs all registered drivers that a socket and function pair is available by first sending a CE_CARD_REMOVAL event code to the callback function of the calling driver, and then sending a CE_CARD_INSERTION event code to each registered client’s callback function.

Driver Name

PCMCIA

See Also

CardRequestExclusive


CardReleaseIRQ

This function stops notification of interrupts on the specified socket and function pair.

Syntax

STATUS CardReleaseIRQ(CARD_CLIENT_HANDLE hCardClient CARD_SOCKET_HANDLE hSocket);

Parameters

hCardClient
Client handle obtained from the CardRegisterClient function.
hSocket
Handle to a socket and function pair.

Return Values

CERR_SUCCESS indicates success. One of the following values indicates failure:

CERR_BAD_HANDLE
Indicates that an hCardClient driver handle is invalid.
CERR_BAD_SOCKET
Indicates that an hSocket socket identifier is invalid or that a PC Card is not inserted.
CERR_CONFIGURATION_LOCKED
Indicates that the CardReleaseConfiguration function must be called to place the PC Card in memory-only mode.

Remarks

This function requires that the PC Card use the memory-only interface. If necessary, call CardReleaseConfiguration to put the PC Card into memory-only interface mode.

Driver Name

PCMCIA

See Also

CardReleaseConfiguration, CardRequestIRQ


CardReleaseSocketMask

This function disables the callbacks requested by the CardRequestSocketMask function for a particular socket and function pair.

Syntax

STATUS CardReleaseSocketMask(CARD_CLIENT_HANDLE hCardClient CARD_SOCKET_HANDLE hSock);

Parameters

hCardClient
Client handle obtained from the CardRegisterClient function.
hSock
Handle to a socket and function pair.

Return Values

CERR_SUCCESS indicates success. One of the following values indicates failure:

CERR_BAD_HANDLE
Indicates that an hCardClient driver handle is invalid.
CERR_BAD_SOCKET
Indicates that an hSock socket identifier is invalid or that no PC Card is inserted in the socket. It can also be returned if no prior call was made to the CardRequestSocketMask function.

Remarks

This function does not disable the global events set by CardRegisterClient.

Driver Name

PCMCIA

See Also

CardRequestSocketMask


CardReleaseWindow

This function releases a memory or I/O window allocated by the CardRequestWindow function.

Syntax

STATUS CardReleaseWindow(CARD_WINDOW_HANDLE hCardWin);

Parameters

hCardWin
Handle to a memory window from CardRequestWindow.

Return Values

CERR_SUCCESS indicates success. One of the following values indicates failure:

CERR_BAD_HANDLE
Indicates that a memory window handle specified for hCardWin is invalid.
CERR_CONFIGURATION_LOCKED
Indicates that the PC Card must be placed in memory-only mode with the CardReleaseConfiguration function before an I/O window can be released.

Driver Name

PCMCIA

See Also

CardRequestWindow, CardReleaseConfiguration


CardRequestConfiguration

This function sets socket attributes, interface type, voltage, and registers, as specified by the CARD_CONFIG_INFO structure.

Syntax

STATUS CardRequestConfiguration(
CARD_CLIENT_HANDLE hCardClient PCARD_CONFIG_INFO pParms);

Parameters

hCardClient
Handle obtained from the CardRegisterClient function.
pParms
Pointer to a CARD_CONFIG_INFO structure.

Return Values

CERR_SUCCESS indicates success. One of the following values indicates failure:

CERR_BAD_ARGS
Indicates that the pointer specified for pParms is invalid.
CERR_BAD_HANDLE
Indicates that the driver specified for hCardClient is invalid.
CERR_BAD_SOCKET
Indicates that the socket identifier specified in the hSocket member of CARD_CONFIG_INFO is invalid or that a PC Card is not inserted.
CERR_BAD_VCC
Indicates that the voltage setting specified in the uVcc member of CARD_CONFIG_INFO is invalid.
CERR_BAD_VPP
Indicates that a voltage setting specified in the uVpp1 or uVpp2 member of CARD_CONFIG_INFO is invalid.
CERR_IN_USE
Indicates that the configuration is owned by another driver.
CERR_WRITE_FAILURE
Indicates that this function is unable to write configuration registers.

Remarks

If power to the socket is off, CardRequestConfiguration turns it on.

Values specified in CARD_CONFIG_INFO are written to the card’s configuration registers.

Driver Name

PCMCIA

See Also

CARD_CONFIG_INFO, CardReleaseConfiguration


CardRequestExclusive

This function requests exclusive access to a specified socket and function pair.

Syntax

STATUS CardRequestExclusive(CARD_CLIENT_HANDLE hCardClient CARD_SOCKET_HANDLE hSocket);

Parameters

hCardClient
Client handle obtained from the CardRegisterClient function.
hSocket
Handle to a socket and function pair.

Return Values

CERR_SUCCESS indicates success. One of the following values indicates failure:

CERR_BAD_HANDLE
Indicates that the driver handle specified for hCardClient is invalid.
CERR_BAD_SOCKET
Indicates that the socket identifier specified for hSocket is invalid or that no PC Card is inserted.
CERR_IN_USE
Indicates that another driver owns exclusive access.

Remarks

This function signals Card Services to issue a series of callback events as it negotiates for approval with each registered driver. First, Card Services sends a CE_EXCLUSIVE_REQUEST event code to all registered drivers to determine if they allow exclusive use. If all drivers approve the request, Card Services sends each driver a CE_CARD_REMOVAL event code. Finally, it sends a CE_CARD_INSERTION event code to the requesting driver followed by a CE_EXCLUSIVE_COMPLETE event code. If any drivers do not approve, Card Services sends the requesting driver a CE_EXCLUSIVE_COMPLETE event code with a failing status in the Parm1 member of the CARD_EVENT_PARMS structure.

Driver Name

PCMCIA

See Also

CardReleaseExclusive


CardRequestIRQ

This function registers an interrupt service callback function for the specified socket and function pair.

Syntax

STATUS CardRequestIRQ(CARD_CLIENT_HANDLE hCardClient CARD_SOCKET_HANDLE hSocket CARD_ISR ISRFunction
UINT32 uISRContextData);

Parameters

hCardClient
Client handle obtained from the CardRegisterClient function.
hSocket
Handle to a socket and function pair.
ISRFunction
Pointer to the interrupt callback function for the specified socket and function pair. This parameter is required.
uISRContextData
Specifies context data to be passed to the interrupt callback function.

Return Values

CERR_SUCCESS indicates success. One of the following values indicates failure:

CERR_BAD_ARGS
Indicates that the pointer specified for ISRFunction is invalid.
CERR_BAD_HANDLE
Indicates that the driver handle specified for hCardClient is invalid.
CERR_BAD_SOCKET
Indicates that the socket identifier specified for hSocket is invalid or that no PC Card is inserted.
CERR_IN_USE
Indicates that another driver owns the configuration or interrupt.
CERR_OUT_OF_RESOURCE
Indicates that a memory window is unavailable to access configuration registers.

Remarks

This function sets up the interrupt callback exclusively for the requesting driver. The device determines the interrupt source, determines which function on a socket interrupted, and calls the appropriate interrupt callback function.

Only I/O drivers can request interrupt notifications. Interrupts are not signaled until the PC Card is configured for the I/O interface by a call to the CardRequestConfiguration function.

Driver Name

PCMCIA

See Also

CardReleaseConfiguration, CardReleaseIRQ


CardRequestSocketMask

This function associates a socket and function pair with an event mask for the driver. Card Services then restricts its future callbacks to the driver to those associated with the event mask passed to this function.

Syntax

STATUS CardRequestSocketMask(CARD_CLIENT_HANDLE hCardClient CARD_SOCKET_HANDLE hSock UINT16 fEventMask);

Parameters

hCardClient
Handle obtained from the CardRegisterClient function.
hSock
Handle to a socket and function pair.
fEventMask
Specifies a bitmask indicating the events that trigger a callback. The allowable card events are listed in the Cardserv.h header file.

Return Values

CERR_SUCCESS indicates success. One of the following values indicates failure:

CERR_BAD_HANDLE
Indicates that the driver handle specified for hCardClient is invalid.
CERR_BAD_SOCKET
Indicates that the socket identifier specified for hSock is invalid.

Remarks

An event mask should not be confused with the global event mask, which pertains to all sockets and is set by CardRegisterClient.

The CardSetEventMask function can change either a socket-specific event mask or the mask specified by CardRegisterClient.

Driver Name

PCMCIA

See Also

CardReleaseSocketMask


CardRequestWindow

This function allocates a window within system memory used to access PC Card memory or I/O space. The window must be mapped by the CardMapWindow function before the window can access the PC Card.

Syntax

CARD_WINDOW_HANDLE CardRequestWindow(CARD_CLIENT_HANDLE hCardClient
PCARD_WINDOW_PARMS pCardWinParms);

Parameters

hCardClient
Client handle obtained from the CardRegisterClient function.
pCardWinParms
Pointer to a CARD_WINDOW_PARMS structure.

Return Values

A driver handle indicates success. NULL indicates failure, and GetLastError returns one of the following values:

CERR_BAD_ARGS
Indicates that the pointer specified for pCardWinParms is invalid.
CERR_BAD_SOCKET
Indicates that the socket identifier specified for the hSocket member for CARD_WINDOW_PARMS is invalid or that no PC Card is inserted.
CERR_OUT_OF_RESOURCE
Indicates that Card Services is unable to allocate memory to track the memory window or that the system has no windows available that match the requested window attributes.

Remarks

This function allocates a memory or an I/O window, according to the values specified in CARD_WINDOW_PARMS. You can use the returned handle for subsequent calls to the CardMapWindow and CardModifyWindow functions.

Driver Name

PCMCIA

See Also

CardMapWindow, CardModifyWindow, CardReleaseWindow


CardResetFunction

This function resets a specified card function in a specified socket.

Syntax

STATUS CardResetFunction(CARD_CLIENT_HANDLE hCardClient CARD_SOCKET_HANDLE hSock);

Parameters

hCardClient
Handle obtained from the CardRegisterClient function.
hSock
Handle to a socket and function pair.

Return Values

CERR_SUCCESS indicates success. One of the following values indicates failure.

CERR_BAD_HANDLE
Indicates that the driver handle specified for hCardClient is invalid.
CERR_BAD_SOCKET
Indicates that the socket identifier specified for hSock is invalid.
CERR_IN_USE
Indicates that another driver owns the configuration for the requested socket.
CERR_NO_CARD
Indicates that no PC Card is inserted in the specified socket.

Remarks

If there are no conflicts, Card Services resets the socket and function pair before this function returns.

Driver Name

PCMCIA

See Also

CARD_EVENT, CardRequestIRQ


CardSetEventMask

This function sets either the driver’s global event mask, set initially by the CardRegisterClient function, or an event mask for a specified socket and function pair as specified in the CARD_EVENT_MASK_PARMS structure.

Syntax

STATUS CardSetEventMask(CARD_CLIENT_HANDLE hCardClient CARD_EVENT_MASK_PARMS pMaskParms);

Parameters

hCardClient
Handle obtained from CardRegisterClient.
pMaskParms
Pointer to a CARD_EVENT_MASK_PARMS structure.

Return Values

CERR_SUCCESS indicates success. One of the following values indicates failure:

CERR_BAD_ARGS
Indicates that the pointer specified for pMaskParms is invalid.
CERR_BAD_HANDLE
Indicates that the driver handle specified for hCardClient is invalid.
CERR_BAD_SOCKET
Indicates that the socket identifier specified for the hSocket member of CARD_EVENT_MASK_PARMS is invalid or that no PC Card is inserted.

Remarks

If the global event mask is requested, the socket identifier in CARD_EVENT_MASK_PARMS is ignored.

To specify event masks for use with a particular socket, call the CardRequestSocketMask function.

Driver Name

PCMCIA

See Also

CARD_EVENT_MASK_PARMS, CardGetEventMask, CardRequestSocketMask


ClearFeature

This function sends a CLEAR_FEATURE request to a USB device.

Syntax

USB_TRANSFER ClearFeature(USB_HANDLE hDevice, LPTRANSFER_NOTIFY_ROUTINE lpStartAddress,
LPVOID lpvNotifyParameter, DWORD dwFlags, WORD wFeature,
UCHAR bIndex);

Parameters

hDevice
[IN] Handle to a USB device.
lpStartAddress
[IN] Pointer to the address, which may be NULL, of a callback routine.
lpvNotifyParameter
[IN] Pointer to the parameter to pass to a callback routine.
dwFlags
[IN] Specify USB_NO_WAIT or 0, plus one of the following:
USB_SEND_TO_DEVICE
Request for device.
USB_SEND_TO_INTERFACE
Request for interface.
USB_SEND_TO_ENDPOINT
Request for endpoint.
wFeature
[IN] Feature selector; one of USB_FEATURE_* declared in the USB100.h header file.
bIndex
[IN] Specifies 0 for DEVICE or the interface or endpoint number.

Return Values

A USB_TRANSFER handle indicates success. NULL indicates failure.

Remarks

This function initiates a control transfer to a USB device, requesting that a specified feature be disabled.

This function is defined in the Mousedrv.cpp file.

See Also

AbortTransfer, GetTransferStatus, IsTransferComplete, SetFeature


ClosePipe

This function closes an open pipe handle.

Syntax

BOOL ClosePipe(USB_PIPE hPipe);

Parameters

hPipe
[IN] Handle to an open pipe.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function aborts all transfers in progress on a pipe and frees all resources associated with the pipe. If transfers are in progress, this function blocks the transfers until the abort completes.

This function is defined in the Mousedrv.cpp file.


CloseTransfer

This function closes an active transfer handle.

Syntax

BOOL CloseTransfer(USB_TRANSFER hTransfer);

Parameters

hTransfer
[IN] Handle to a USB transfer.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function aborts a transfer in progress and frees resources associated with the transfer.

This function is defined in the Mousedrv.cpp file.


COM_Close

This function closes the serial device. It is called in response to an application’s call to the CloseHandle function.

Syntax

BOOL COM_Close(DWORD pContext);

Parameters

pContext
Context pointer returned from the COM_Open function.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

The Device Manager calls this routine to close the device.

This function is defined in the Mdd.c file.

See Also

COM_Init, COM_Open


COM_Deinit

This function de-initializes the serial port.

Syntax

BOOL COM_Deinit(void);

Return Values

None.

Remarks

This function is called by the DeregisterDevice function, which is exposed to applications.

This function is defined in the Mdd.c file.

See Also

COM_Init


COM_Init

This function initializes the serial device.

Syntax

HANDLE COM_Init(ULONG Identifier);

Parameters

Identifier
Identifies the port. If a device driver is loaded by Device.exe, this value is an LPWSTR that points to a string containing the registry key within HKEY_LOCAL_MACHINE\Drivers\Active\. If the device driver is loaded by a call to the RegisterDevice function, this value is the dwInfo value passed into the call to RegisterDevice.

Return Values

Returns a pointer to the serial head, which then is passed as a device handle into the entry points COM_Open and COM_Deinit.

Remarks

This function is called at device load time in order to perform any initialization. Typically, this function does as little as possible, postponing memory allocation and device power on until an application calls the driver’s XXX_Open function.

This function is defined in the Mdd.c file.

See Also

COM_Deinit


COM_IOControl

This function implements the serial port’s I\O control routine. It is called by serial port functions such as GetComState, which is a wrapper around this function.

Syntax

BOOL COM_IOControl(DWORD dwOpenData, DWORD dwCode,
PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut);

Parameters

dwOpenData
Specifies a value returned from a call to the COM_Open function.
dwCode
Specifies an I\O control code to be performed.
pBufIn
Pointer to data input to the device.
dwLenIn
Specifies the number of bytes being passed in.
pBufOut
Pointer to data output from the driver.
dwLenOut
Specifies the maximum number of bytes to receive from the driver.
pdwActualOut
Pointer to the actual number of bytes received from the driver.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function is exported by a device driver. “COM” is the string passed in as lpszType during calls to the RegisterDevice function.

This function is defined in the Mdd.c file.

See Also

COM_IOControl


COM_Open

This function initializes the serial port driver.

Syntax

HANDLE COM_Open(HANDLE pContext, DWORD AccessCode,
DWORD ShareMode);

Parameters

pContext
Pointer to a handle returned by the COM_Init function.
AccessCode
Specifies the access level requested by the caller, such as shared read or read/write.
ShareMode
Specifies the sharing mode that the calling application passed to the CreateFile function.

Return Values

Returns a handle representing the serial port.

Remarks

The user calls this function to open the serial device. The HANDLE returned must be used by the application in all subsequent calls to the serial driver. This function starts the thread that handles the serial events. This function is exported to applications through CreateFile. It is defined in the Mdd.c file.

See Also

COM_Close


COM_PowerDown

This function indicates to the serial port driver that the platform is about to go into suspend mode.

Syntax

BOOL COM_PowerDown(HANDLE pContext);

Parameters

pContext
Pointer to a handle to the device.

Return Values

Zero indicates success. A value of 1 indicates failure.

Remarks

This function is exported to users. As with all power-down handlers, this function cannot call functions in other DLLs, memory allocators, debugging output functions, or do anything that could cause a page fault.

This function is defined in the Mdd.c file.

See Also

COM_PowerUp


COM_PowerUp

This function indicates to the serial port driver that the platform is resuming from suspend mode.

Syntax

BOOL COM_PowerUp(HANDLE pContext);

Parameters

pContext
Pointer to a handle to the device.

Return Values

Zero indicates success. A value of 1 indicates failure.

Remarks

This function is exported to users. As with all power-up handlers, this function cannot call functions in other DLLs, memory allocators, debugging output functions, or do anything that could cause a page fault.

This function is defined in the Mdd.c file.

See Also

COM_PowerDown


COM_Read

This function enables an application to receive characters from the serial port.

Syntax

ULONG COM_Read(HANDLE pContext, PUCHAR pTargetBuffer,
ULONG BufferLength);

Parameters

pContext
Pointer to a handle returned by the COM_Open function.
pTargetBuffer
Pointer to valid memory.
BufferLength
Specifies the size, in bytes, of pTargetBuffer.

Return Values

The number of bytes read indicates success. A value of -1 indicates failure.

Remarks

This function sets the buffer and buffer length requested by the caller. It writes the number of bytes transacted and returns the status of the call.

This function is exported to users through the ReadFile function.

This function must obey time-out values set for the serial port.

This function is defined in the Mdd.c file.

See Also

COM_Write


COM_Write

This function enables an application to transmit bytes to the serial port.

Syntax

ULONG COM_Write(HANDLE COM_Write, PUCHAR pSourceBytes, ULONG NumberOfBytes);

Parameters

COM_Write
Handle returned by the COM_Open function.
pSourceBytes
Pointer to bytes to be written.
NumberOfBytes
Specifies the number of bytes to be written.

Return Values

The number of bytes written indicates success. A value of –1 indicates failure.

Remarks

This function is exported to users through the WriteFile function. This function must obey flow-control and time-out values.

This function is defined in the Mdd.c file.

See Also

COM_Read


CompareString

This function compares two character strings, using the locale specified by the identifier as the basis for the comparison.

Syntax

int CompareString(LCID Locale, DWORD dwCmpFlags,
LPCTSTR lpString1, int cchCount1, LPCTSTR lpString2, int cchCount2);

Parameters

Locale
Specifies the locale used for the comparison. This parameter can be one of the following predefined locale identifiers:
LOCALE_SYSTEM_DEFAULT
The system’s default locale
LOCALE_USER_DEFAULT
The current user’s default locale

This parameter can also be a locale identifier created by the MAKELCID macro.

dwCmpFlags
Indicate how this function compares the two strings. The SORT_STRINGSORT flag is assumed and cannot be disabled. The NORM_IGNORECASE flag can be added as an option to ignore differences between uppercase and lowercase characters in the two strings.
lpString1
Pointer to the first string to be compared.
cchCount1
Specifies the number of characters in the string pointed to by the lpString1 parameter. If this parameter is –1, the string is assumed to be null terminated, and the length is calculated automatically.
lpString2
Pointer to the second string to be compared.
cchCount2
Specifies the number of characters in the string pointed to by the lpString2 parameter. If this parameter is –1, the string is assumed to be null terminated, and the length is calculated automatically.

Return Values

One of the following values indicates success:

1
The string pointed to by the lpString1 parameter is less in lexical value than the string pointed to by the lpString2 parameter.
2
The string pointed to by lpString1 is equal in lexical value to the string pointed to by lpString2.
3
The string pointed to by lpString1 is greater in lexical value than the string pointed to by lpString2.

Zero indicates failure, and GetLastError may return one of the following error values:

  • ERROR_INVALID_FLAGS
  • ERROR_INVALID_PARAMETER

If the return value is 2, the two strings are equal in the collation sense, though not necessarily identical.

Remarks

To maintain the C run-time convention of comparing strings, the return value for strings that are equal can be 0, instead of 2.

Currently, this function is available only in Windows CE version 2.10.


CONTAINING_RECORD

This macro returns the base address of an instance of a structure of a specified type if it has the address of a member within the containing structure.

At a Glance

Header file: | Winnt.h
Windows CE versions: | 2.0 and later

Syntax

PCHAR CONTAINING_RECORD(IN PCHAR Address, IN TYPE Type,
IN PCHAR Field);

Parameters

Address
Pointer to a field in an instance of a structure of type Type.
Type
The name of the type of the structure whose base address is to be returned, for example, type IRP.
Field
The name of the field pointed to by Address contained in a structure of type Type.

Return Values

Returns a pointer to the base of the structure containing Field.

Remarks

This macro is called to determine the base address of a structure whose type is known when the caller has a pointer to a field inside such a structure. This macro is useful for symbolically accessing other fields in a structure of known type.

A driver that calls this macro can be running at any IRQ level as long, as the structure is resident. If a page fault might occur, callers must be at or below IRQ level APC_LEVEL.


DdsiTouchPanelDisable

This function disables the touch screen device. Disabling a touch screen prevents generation of any subsequent touch samples, and removes power from the screen's hardware. The exact steps necessary depend on the specific characteristics of the touch screen hardware.

Syntax

ULONG DdsiTouchPanelDisable(void);

Remarks

This function supports the implementation of the touch screen driver.


DdsiTouchPanelEnable

This function applies power to the touch screen device and initializes it for operation.

Syntax

BOOL DdsiTouchPanelEnable(void);

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function supports the implementation of the touch screen driver.


DdsiTouchPanelGetDeviceCaps

This function queries capabilities of the touch screen device.

Syntax

ULONG DdsiTouchPanelGetDeviceCaps(ULONG iIndex, LPVOID lpOutput);

Parameters

iIndex
Specifies one of the following capabilities to query:
TPDC_SAMPLERATE_ID
The sample rate.
TPDC_CALIBRATIONPOINTS_ID
The x-coordinate and y-coordinate used for calibration.
TPDC_CALIBRATIONDATA_ID
The x-coordinate and y-coordinate used for calibration mapping.
lpOutput
Pointer to the memory location(s) where the queried information should be placed. The format of the memory referenced depends on the setting of iIndex. If it is 0, this function returns the number of WORDs required for the output data.

Return Values

The return values are set to the amount of information supplied and depend on the setting of the iIndex parameter.

Remarks

This function supports the implementation of the touch screen driver.


DdsiTouchPanelGetPoint

This function returns the most recently acquired point and its associated tip state information.

Syntax

void DdsiTouchPanelGetPoint(
PDDSI_TOUCHPANEL_TIPSTATE pTipState, PLONG pUnCalX,
PLONG pUnCalY);

Parameters

pTipState
Pointer to where the tip state information should be returned.
pUnCalX
Pointer to where the x-coordinate should be returned.
pUnCalY
Pointer to where the y-coordinate should be returned.

Remarks

This function supports the implementation of the touch screen driver.


DdsiTouchPanelPowerHandler

This function indicates to the driver that the system is entering or leaving the suspend state.

Syntax

VOID DdsiTouchPanelPowerHandler(BOOL bOff);

Parameters

bOff
TRUE indicates that the system is being turned off. FALSE indicates that the system is being turned on.

Remarks

As with all power-down handlers, this function cannot call functions in other DLLs, memory allocators, debugging output functions, or do anything that could cause a page fault. This routine is called by the MDD.


DdsiTouchPanelSetMode

This function sets information about the touch screen device.

Syntax

BOOL DdsiTouchPanelSetMode(ULONG iIndex, LPVOID lpInput);

Parameters

iIndex
Specifies the mode to set. One of the following:
TPSM_SAMPLERATE_HIGH_ID
Sets the sample rate to the high rate.
TPSM_SAMPLERATE_LOW_ID
Sets the sample rate to the low rate.
lpInput
Pointer to the memory location(s) where the update information resides. Points to the memory location(s) where the queried information should be placed.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function supports the implementation of the touch screen driver.


DeregisterDevice

This function deregisters a registered device.

Syntax

BOOL DeregisterDevice(Handle hDevice);

Parameters

hDevice
Handle to a registered device returned from the RegisterDevice function.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

The Device Manager calls this function when a device is removed from the system or if the system is being shut down. This function calls the device driver’s XXX_Deinit function.


DrvCopyBits

This function translates between device-managed raster surfaces and GDI standard format bitmaps.

Syntax

BOOL DrvCopyBits(OUT SURFOBJ *psoDst, IN SURFOBJ *psoSrc,
IN CLIPOBJ *pco, IN XLATEOBJ *pxlo, IN RECTL *prclDst,
IN POINTL *pptlSrc);

Parameters

psoDst
Pointer to the destination surface for the copy operation.
psoSrc
Pointer to the source surface for the copy operation.
pco
Pointer to a CLIPOBJ structure that defines a clipping region on the destination surface.
pxlo
Pointer to a XLATEOBJ structure that defines the translation of color indices between the source and target surfaces.
prclDst
Points to a RECTL structure that defines the area to be modified. This structure uses the coordinate system of the destination surface. The bottom and right edges of this rectangle are not part of the bit-block transfer (blit); that is, the rectangle is bottom-right exclusive.

This function is never called with an empty destination rectangle. The two points that define the rectangle are always well ordered.

pptlSrc
Pointer to a POINTL structure that defines the upper-left corner of the source rectangle.

Return Values

TRUE indicates success.

Remarks

This function is required for a device driver that has device-managed bitmaps or raster surfaces. The implementation in the driver must translate driver surfaces to and from any standard-format bitmap.

Standard-format bitmaps are single-plane, packed-pixel format. Each scan line is aligned on a 4-byte boundary. These bitmaps have 1, 4, 8, 16, 24, 32, or 64 bits per pixel.

This function should ideally be able to deal with run-length encloding and device-dependent bitmaps. The device-dependent format is optional; only a few specialized drivers need to support it. These bitmaps can be sent to this function as a result of the following GDI functions: SetDIBits, SetDIBitsToDevice, GetDIBits, SetBitmapBits, and GetBitmapBits.

Kernel-mode GDI calls this function from its simulations.


DrvDisablePDEV

This function is used by MGDI to notify a driver that the specified PDEV structure is no longer needed.

Syntax

VOID DrvDisablePDEV(IN DHPDEV dhpdev);

Parameters

dhpdev
Pointer to the PDEV that describes the physical device to be disabled. This value is the handle returned by the DrvEnablePDEV function.

Remarks

If the driver has been disabled by a call to the DrvEnablePDEV function, the driver cannot access the hardware during a call to the DrvDisableSurface function because another active surface might be in use. Any necessary hardware changes should have been performed during the call to the DrvAssertMode function. A driver should keep track of whether or not it has been disabled by DrvAssertMode so that it can perform proper cleanup operations in DrvDisableSurface.

If the physical device has an enabled surface, the GDI calls this function after calling DrvDisableSurface. The driver should free any memory and resources used by the PDEV.

This function is required for graphics drivers.


DrvDisableSurface

This function is used by the GDI to notify a driver that the surface created by the DrvEnableSurface function for the current device is no longer needed.

Syntax

VOID DrvDisableSurface(IN DHPDEV dhpdev);

Parameters

dhpdev
Handle to the PDEV structure that describes the physical device whose surface is to be released.

Remarks

The driver should free any memory and resources used by the surface associated with PDEV as soon as the physical device is disabled.

If the driver has been disabled by a call to the DrvAssertMode function, the driver cannot access the hardware during a call to the DrvDisablePDEV function because another active PDEV might be in use. Any necessary hardware changes should have been performed during the call to DrvAssertMode. A driver should keep track of whether or not it has been disabled by DrvAssertMode so that it can perform proper cleanup operations in DrvDisablePDEV.

If the physical device has an enabled surface, the GDI calls this function before calling DrvDisablePDEV.

This function is required for graphics drivers.

See Also

DrvDisablePDEV


DrvEnableDriver

This function is the initial driver entry point exported by the driver DLL. It fills a DRVENABLEDATA structure with the driver version number and calling addresses of functions supported by the driver.

Syntax

BOOL DrvEnableDriver(IN ULONG iEngineVersion, IN ULONG cj,
OUT DRVENABLEDATA *pded);

Parameters

iEngineVersion
Specifies the DDI version number that the GDI was written for. DDI_DRIVER_VERSION is always the current version; drivers should use this manifest constant, declared in the Winddi.h header file.
cj
Specifies the size, in bytes, of the DRVENABLEDATA structure. If the structure is larger than expected, extra members should be left unmodified.
pded
Pointer to a DRVENABLEDATA structure. The GDI 0-initializes cj bytes before the call. The driver fills in its own data.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

One-time initializations, such as allocating semaphores, can be performed by this function. The driver should wait until the DrvEnablePDEV function is called before enabling hardware, such as a display.

This function is required for graphics drivers.


DrvEnablePDEV

This function enables a device context for drawing and returns device metrics for the target printer or display device in a GDIINFO structure. Printer drivers call a display driver's DrvEnablePDEV function to create and itialize the DC, and then substitute the printer's device metrics before returning the DC to the GDI for bitmap rendering.

DHPDEV APIENTRY DrvEnablePDEV(
DEVMODEW *pdm,
LPWSTR pwszLogAddress,
ULONG cPat,
HSURF *phsurfPatterns,
ULONG cjCaps,
ULONG *pdevcaps,
ULONG cjDevInfo,
DEVINFO *pdi,
HDEV hdev,
LPWSTR pwszDeviceName,
HANDLE hDriver);

Return Values

A valid DHPDEV indicates success. Zero indicates failure.


DrvEnableSurface

This function sets up a surface to be drawn on and associates it with a specified PDEV.

Syntax

HSURF DrvEnableSurface(IN DHPDEV dhpdev);

Parameters

dhpdev
Handle to a PDEV structure. This value is the return value of the DrvEnablePDEV function. The PDEV describes the physical device for which a surface is to be created.

Return Values

A handle that identifies the newly created surface indicates success. Zero indicates failure.

Remarks

Depending on the device and circumstances, the driver can do any of the following to enable the surface:

  • If the driver manages its own surface, the driver can call the EngCreateDeviceSurface function to get a handle to the surface.
  • The GDI can manage the surface completely if the device has a surface that resembles a standard format bitmap. The driver can obtain a bitmap handle for the surface by calling the EngCreateBitmap function with a pointer to the buffer for the bitmap.
  • The GDI can collect the graphics directly onto a GDI bitmap. The driver should call EngCreateBitmap, allowing the GDI to allocate memory for the bitmap. This function is generally used only by printer devices.

Any existing GDI bitmap handle is a valid surface handle.

Before defining and returning a surface, a graphics driver must associate the surface with the physical device using the EngAssociateSurface function. This GDI function allows the driver to specify which graphics output routines are supported for standard format bitmaps. A call to this function can only be made when no surface exists for the specified physical device.

This function is required for graphics drivers.

See Also

DrvDisableSurface


DrvEndDoc

This function causes the driver to send any control information needed at the end of a document.

Syntax

BOOL DrvEndDoc(IN SURFOBJ *pso, IN FLONG fl);

Parameters

pso
Pointer to a SURFOBJ structure that defines the surface object. The structure can be queried to find its type and what PDEV structure it is associated with.
fl
Specifies a set of flags. If the ED_ABORTDOC flag is set, the print job has been canceled or aborted.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function is required for printer drivers.


DrvGetModes

This function lists the modes supported by a specified device.

Syntax

ULONG DrvGetModes(IN HANDLE hDriver, IN ULONG cjSize,
OUT DEVMODEW *pdm);

Parameters

hDriver
Handle to the kernel driver for which the modes must be enumerated. This is the handle that is passed in the hDriver parameter of the DrvEnablePDEV function.
cjSize
Specifies the size, in bytes, of the buffer pointed to by pdm.
pdm
Pointer to the buffer in which DEVMODEW structures will be written.

Return Values

Returns the count of bytes written to the buffer, or, if pdm is null, the number of bytes required to hold all mode data. Zero indicates failure.

Remarks

This function is required for display drivers. It is called indirectly by the Display option in Control Panel to get the list of supported modes.

The Window Manager (User.exe) dynamically loads all display drivers associated with a miniport, based on the InstalledDisplayDrivers key in the registry. Each display driver is called to retrieve the list of modes supported by that combination of loaded drivers. For example, the VGA64K display driver only returns the 64-KB color modes that were returned in the list of modes obtained from the miniport driver.

This function can be called even when the display driver has not been loaded.


DrvStartDoc

This function sends any control information needed at the start of a document.

Syntax

BOOL DrvStartDoc(IN SURFOBJ *pso, IN PWSTR pwszDocName,
IN DWORD dwJobId);

Parameters

pso
Pointer to the surface object. The object can be queried to find its type and which PDEV structure it is associated with.
pwszDocName
Pointer to a 0-terminated Unicode string specifying the user-readable name of the document being printed.
dwJobId
Identifies the print job. This value is returned to the GDI from the spooler in a call to the StartDocPrinter function.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

The control codes should be sent using the WritePrinter function.

This function is required for printer drivers.


DrvStartPage

This function requests the driver to send any control information needed at the start of a page. The control codes is sent using the EngWritePrinter function.

Syntax

BOOL DrvStartPage(IN SURFOBJ *pso);

Parameters

pso
Pointer to the surface object. The object can be queried to find its type and which PDEV structure it is associated with.

Return Values

TRUE indicates success. FALSE indicate failure.

Remarks

This function is required for printer drivers.


DSK_Init

This function initializes solid state disk devices, such as ATA, SRAM, and linear flash memory disks. After loading the device’s driver DLL, the Device Manager calls this function and passes to it the active key that contains the socket number. This function verifies that the media is accessible. It then creates a client context structure for the socket. Next, it registers itself as a client driver with PC Card Services, if any PC Card or minicard is in use. Finally, it calls the CardRequestWindow and CardMapWindow functions to map the disk memory to device memory.


DSK_Close

This function decrements the open reference count. If the open reference count is 0, this function marks the disk as closed.


DSK_Deinit

This function calls the CardReleaseWindow function for all mapped windows. It then calls the CardDeregisterClient function to free the client context.


DSK_Open

This function is called by the Device Manager when the FAT file system opens the storage device through the CreateFile function. This function mounts the media and increments the open reference count.


DSK_IOControl

This function responds to file allocation table (FAT) requests to read and write data; get media information, such as geometry; set media information; get device names; and perform low-level formatting operations.


DSK_PowerUp

The Device Manager calls this function to process POWER-UP notifications from the kernel.


DSK_PowerDown

The Device Manager calls this function to process POWER-DOWN notifications from the kernel.


ErrorAnalysis

This function provides information on the accuracy of the touch screen calibration.

Syntax

VOID ErrorAnalysis(INT32 cCalibrationPoints, INT32 *pScreenXBuffer, INT32 *pScreenYBuffer, INT32 *pUncalXBuffer, INT32 *pUncalYBuffer);

Parameters

cCalibrationPoints
Specifies the number of calibration points.
pScreenXBuffer
Pointer to the list of screen x-coordinates displayed.
pScreenYBuffer
Pointer to the list of screen y-coordinates displayed.
pUncalXBuffer
Pointer to the list of x-coordinates collected.
pUncalYBuffer
Pointer to the list of y-coordinates collected.

Remarks

This function is defined in the Calibrat.c file.


ETH_COPY_NETWORK_ADDRESS

This macro copies a specified Ethernet address to a specified location.

At a Glance

Header file: | Efilter.h
Windows CE versions: | 2.0 and later

Syntax

VOID ETH_COPY_NETWORK_ADDRESS(OUT PCHAR D, IN CHAR S);

Parameters

D
Pointer to a caller-supplied varible to which this function copies the source address.
S
Pointer to the source address.

Remarks

A driver that calls this macro can be running at any IRQL, as long as the source and destination address pointers are resident.


EthChangeFilterAddresses

This function is called by an NIC driver to attempt to change the multicast address list for a binding filter in the Ethernet filter library database.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

NDIS_STATUS EthChangeFilterAddresses(
IN PETH_FILTER Filter, IN NDIS_HANDLE NdisFilterHandle,
IN PNDIS_REQUEST NdisRequest, IN UINT AddressCount,
IN CHAR Addresses[][ETH_LENGTH_OF_ADDRESS], IN BOOLEAN Set);

Parameters

Filter
Pointer to a previously created and initialized filter library database.
NdisFilterHandle
Handle that the filter library associates with the binding filter.
NdisRequest
Pointer to the request structure that this function passes to an NIC driver action function.
AddressCount
Specifies the number of elements to be added to the multicast address list.
Addresses[][ETH_LENGTH_OF_ADDRESS]
Specifies a two-dimensional character array that contains the new multicast address list for the specified binding. The ETH_LENGTH_OF_ADDRESS constant specifies the length, in bytes, of an Ethernet address declared in the Efilter.h header file. The array is a sequence of 48-bit Ethernet addresses with no padding between addresses.
Set
Specifies TRUE if changes do not result from the closing of the binding. This function does not use this value but passes it to an NIC driver action function.

Return Values

NDIS_STATUS_SUCCESS indicates success. One of the following indicates failure:

  • NDIS_STATUS_MULTICAST_FULL
  • NDIS_STATUS_PENDING

Remarks

If this function does not change the multicast address list for a binding filter, it has no effect on the filter address list or the multicast address list for the NIC. If this function does change the filter address list, it calls an NIC driver action function and waits for it to return. If the action function returns a status code that indicates neither pending nor success, this function restores the filter library database to its original state.

A caller must be holding the database spin lock to call this function, so the driver is running at IRQL DISPATCH_LEVEL.


EthCreateFilter

This function is called by an NIC driver. It creates and initializes an Ethernet filter library database associated with one network interface card (NIC).

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

BOOLEAN EthCreateFilter(IN UINT MaximumMulticastAddresses,
IN ETH_ADDRESS_CHANGE AddressChangeAction,
IN ETH_FILTER_CHANGE FilterChangeAction,
IN ETH_DEFERRED_CLOSE CloseAction, IN PUCHAR AdapterAddress, IN PNDIS_SPIN_LOCK Lock, OUT PETH_FILTER *Filter);

Parameters

MaximumMulticastAddresses
Specifies the maximum number of multicast addresses supported by the filter.
AddressChangeAction
Handle to the caller’s MacChangeEthAddresses function, which the Ethernet filter library calls when a change occurs in the list of multicast addresses that the network interface card enables.
FilterChangeAction
Handle to the caller’s MacChangeFilter function, which the Ethernet filter library calls when a binding sets or clears a particular filter class. The binding must be the first or only binding using the filter class.
CloseAction
Specifies the address of the caller’s MacCloseAction function, which the Ethernet filter library calls if a binding closes while it is indicating incoming data through the NdisMEthIndicateReceive function.
AdapterAddress
Pointer to the network address of the NIC.
Lock
Pointer to an initialized spin lock that the driver must hold when it requires exclusive access to the Ethernet filter library database.
Filter
Pointer to a caller-supplied variable in which this function writes a pointer to the created filter.

Return Values

TRUE indicates success.

Remarks

The NIC driver uses the Ethernet filter library to filter received network packets. Using the destination address of a received packet, the filter library determines the protocol driver bindings that receive indications for the packet.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

EthDeleteFilter, NdisAllocateSpinLock, NdisMEthIndicateReceive


EthDeleteFilter

This function is called by an NIC driver to delete the memory associated with an Ethernet filter library database.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID EthDeleteFilter(IN PETH_FILTER Filter);

Parameters

Filter
Pointer to the filter library database memory to be deleted.

Remarks

This function assumes that any active filters have been cleared from the database.

Drivers usually call this function when they are unloading.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

EthCreateFilter


EthDeleteFilterOpenAdapter

This function is called by an NIC driver to delete NIC binding filter information from the Ethernet filter library database.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

NDIS_STATUS EthDeleteFilterOpenAdapter(IN PETH_FILTER Filter,
IN NDIS_HANDLE NdisFilterHandle, IN PNDIS_REQUEST NdisRequest);

Parameters

Filter
Pointer to a previously created and initialized filter library database.
NdisFilterHandle
Handle that the filter library associates with the binding filter.
NdisRequest
Pointer to the request structure that this function passes to an NIC driver action function.

Return Values

NDIS_STATUS_SUCCESS indicates success. One of the following indicates failure:

  • NDIS_STATUS_CLOSING_INDICATING
  • NDIS_STATUS_PENDING

Remarks

This function calls an NIC driver’s functions associated with clearing filter classes and addresses. The NIC driver should not call this function if the action functions can return a status code that indicates neither pending nor success.

The NIC driver must be holding the filter library spin lock when it calls this function.

A driver that calls this function runs at IRQL DISPATCH_LEVEL.

See Also

EthNoteFilterOpenAdapter


EthFilterAdjust

This function is called by an NIC driver to adjust an Ethernet filter library database.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

NDIS_STATUS EthFilterAdjust(IN PETH_FILTER Filter,
IN NDIS_HANDLE NdisFilterHandle, IN PNDIS_REQUEST NdisRequest,
IN UINT FilterClasses, IN BOOLEAN Set);

Parameters

Filter
Pointer to a previously created and initialized filter library database.
NdisFilterHandle
Handle that the filter library associates with the binding filter.
NdisRequest
Pointer to the request structure that this function passes to an NIC driver action function.
FilterClasses
Specifies a bitmap of filter classes that this function adds and deletes.
Set
Specifies TRUE if changes do not result from the closing of the binding. This function does not use Set but passes it to an NIC driver action function.

Return Values

NDIS_STATUS_SUCCESS indicates success. The following indicate failure:

  • NDIS_STATUS_PENDING
  • NDIS_STATUS_RESET_IN_PROGRESS

Remarks

This function calls an NIC driver’s function if no binding has used a particular filter class and at least one binding starts using that class. This function also calls an action function for the reverse situation. If the NIC driver action function returns a status code that indicates neither pending nor success, this function restores the filter library database to its original state.

The NIC driver must be holding the filter library spin lock when it calls this function.

A driver that calls this function runs at IRQL DISPATCH_LEVEL.


EthFilterIndicateReceive

This function is called by an NIC driver to indicate a received packet to all filter library database bindings associated with an Ethernet address.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID EthFilterIndicateReceive(IN PETH_FILTER Filter,
IN NDIS_HANDLE MacReceiveContext, IN PCHAR Address,
IN PVOID HeaderBuffer, IN UINT HeaderBufferSize,
IN PVOID LookaheadBuffer, IN UINT LookaheadBufferSize,
IN UINT PacketSize);

Parameters

Filter
Pointer to a previously created and initialized filter library database.
MacReceiveContext
Specifies a context that the NIC driver associates with a packet received from the network.
Address
Pointer to the destination address that the NIC driver has already extracted from the received packet.
HeaderBuffer
Pointer to the virtual address of the virtually contiguous buffer containing the packet header. The buffer is valid only within the current call to this function.
HeaderBufferSize
Indicates the length, in bytes, of the packet header.
LookaheadBuffer
Pointer to the virtual address of the virtually contiguous buffer containing the first bytes of packet data. The packet buffer is valid only for the current call to this function.
LookaheadBufferSize
Specifies the size, in bytes, of the look-ahead buffer.
PacketSize
Specifies the size, in bytes, of the received packet data. This parameter number is not related to the look-ahead buffer, but rather indicates the size of the received packet data. This allows a protocol driver to call the NdisTransferData function and to transfer data in the packet, as necessary. The data length does not include the packet header length.

Remarks

Instead of calling NdisIndicateReceive without filtering, the NIC driver calls this function to filter a received packet so that only the appropriate bindings receive it. This function then calls the ProtocolReceive function of each protocol driver to which the binding filter applies.

In its calls to ProtocolReceive, this function passes each protocol driver a pointer to the packet header as well as a pointer to some or all of the packet data. The protocol driver can inspect the header and data in the packet, optionally copy as much of the header or data as is visible, or optionally call NdisTransferData to instruct the NIC driver to copy the data into a protocol-supplied packet.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

See Also

EthFilterIndicateReceiveComplete, NdisMEthIndicateReceive, NdisTransferData


EthFilterIndicateReceiveComplete

This function is called by an NIC driver to indicate to all bound protocol drivers that the EthFilterIndicateReceive function has returned.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID EthFilterIndicateReceiveComplete(IN PETH_FILTER Filter);

Parameters

Filter
Pointer to a previously created and initialized Ethernet filter library database.

Remarks

To deliver the necessary indications, this function calls each protocol’s ProtocolReceiveComplete function once for each indication.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

See Also

EthFilterIndicateReceive


EthNoteFilterOpenAdapter

This function is called by the NIC driver to add a binding filter to the Ethernet filter library database.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

BOOLEAN EthNoteFilterOpenAdapter(IN PETH_FILTER Filter,
IN NDIS_HANDLE MacBindingHandle,
IN NDIS_HANDLE NdisBindingContext,
OUT PNDIS_HANDLE NdisFilterHandle);

Parameters

Filter
Pointer to a previously created and initialized filter library database.
MacBindingHandle
Handle that the NIC driver associates with the binding.
NdisBindingContext
Specifies the context that the NDIS interface library associates with the binding.
NdisFilterHandle
Pointer to a caller-supplied memory location in which this function returns the handle that the filter library associates with the binding filter.

Return Values

TRUE indicates success. FALSE indicates that the database already contains the maximum number of filters.

Remarks

A caller must be holding the database spin lock to call this function, so the driver is running at IRQL DISPATCH_LEVEL.

See Also

EthDeleteFilterOpenAdapter


EthNumberOfOpenFilterAddresses

This function is called by the NIC driver to count the number of Ethernet filter library database multicast addresses in a binding filter.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

UINT EthNumberOfOpenFilterAddresses(IN PETH_FILTER Filter,
IN NDIS_HANDLE NdisFilterHandle);

Parameters

Filter
Pointer to a previously created and initialized filter library database.
NdisFilterHandle
Handle that the filter library associates with the binding filter.

Return Values

Returns the number of multicast addresses in the binding filter.

Remarks

A caller must be holding the database spin lock to call this function, so the driver is running at IRQL DISPATCH_LEVEL.

See Also

EthQueryOpenFilterAddresses


EthQueryGlobalFilterAddresses

This function is called by the NIC driver to query the Ethernet filter library database for a list of multicast addresses associated with the network interface card.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID EthQueryGlobalFilterAddresses( OUT PNDIS_STATUS Status,
IN PETH_FILTER Filter, IN UINT SizeOfArray,
OUT PUINT NumberOfAddresses,
IN OUT CHAR AddressArray[][ETH_LENGTH_OF_ADDRESS]);

Parameters

Status
Points to a caller-supplied variable in which this function returns the status of the query operation. Possible values are the following:
  • NDIS_STATUS_FAILURE
  • NDIS_STATUS_SUCCESS
Filter
Pointer to a previously created and initialized filter library database.
SizeOfArray
Specifies the byte count for the two-dimensional array to hold the addresses.
NumberOfAddresses
Pointer to the caller-supplied variable in which this function returns the number of addresses that it writes to the array.
AddressArray[][ETH_LENGTH_OF_ADDRESS]
Specifies the two-dimensional caller-supplied array in which this function returns addresses currently associated with the network interface card.

Remarks

The NIC driver calls this function before it alters registers on the NIC to effect filtering. The timing of the call is important if a binding has altered the multicast address list. Before calling this function, the NIC driver uses the ETH_NUMBER_OF_GLOBAL_FILTER_ADDRESSES macro to obtain the number of multicast addresses to be retrieved.

A caller must be holding the database spin lock to call this function, so the driver is running at IRQL DISPATCH_LEVEL.


EthQueryOpenFilterAddresses

This function is called by the NIC driver to query the Ethernet filter library database for a list of multicast addresses associated with a binding.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID EthQueryOpenFilterAddresses(OUT PNDIS_STATUS Status,
IN PETH_FILTER Filter, IN NDIS_HANDLE NdisFilterHandle,
IN UINT SizeOfArray, OUT PUINT NumberOfAddresses,
OUT CHAR AddressArray[][ETH_LENGTH_OF_ADDRESS]);

Parameters

Status
Pointer to a caller-supplied variable in which this function returns the status of the query operation. Possible values are the following:
  • NDIS_STATUS_FAILURE
  • NDIS_STATUS_SUCCESS
Filter
Pointer to a previously created and initialized filter library database.
NdisFilterHandle
Handle that the filter library associates with the binding filter.
SizeOfArray
Specifies the byte count for the two-dimensional array to contain the addresses.
NumberOfAddresses
Pointer to the caller-supplied variable in which this function returns the number of addresses that it writes to the array.
AddressArray[][ETH_LENGTH_OF_ADDRESS]
Specifies the two-dimensional caller-supplied array to which this function writes addresses currently associated with the binding.

Remarks

The NIC driver calls this function before it alters registers on the NIC to effect filtering. The timing of the call is important if another binding has altered the multicast address list. Before calling this function, the NIC driver calls the EthNumberOfOpenFilterAddresses function to obtain the number of multicast addresses to be retrieved.

A caller must be holding the database spin lock to call this function, so the driver is running at IRQL DISPATCH_LEVEL.

See Also

EthNumberOfOpenFilterAddresses


EthShouldAddressLoopBack

This function returns FALSE if a packet bound for a given Ethernet address cannot possibly loop back.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

BOOLEAN EthShouldAddressLoopBack(IN PETH_FILTER Filter,
IN CHAR Address[ETH_LENGTH_OF_ADDRESS]);

Parameters

Filter
Pointer to a previously created and initialized filter library database.
Address[ETH_LENGTH_OF_ADDRESS]
Specifies an Ethernet address that this function uses to determine a need for packet loopback.

Return Values

Returns TRUE if the packet is likely to loop back. It returns FALSE if there is no chance the packet will loop back.

Remarks

This function does not check whether the source address is equal to the destination address.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

See Also

ETH_COPY_NETWORK_ADDRESS


FindInterface

This function searches for a specific interface on a device.

Syntax

LPCUSB_INTERFACE FindInterface(LPCUSB_DEVICE lpDeviceInfo, UCHAR bInterfaceNumber, UCHAR bAlternateSetting);

Parameters

lpDeviceInfo
[IN] Pointer to a device information structure, which is returned from the GetDeviceInfo function.
bInterfaceNumber
[IN] Specifies the interface number.
bAlternateSetting
[IN] Specifies an alternate interface setting.

Return Values

A pointer to a USB_INTERFACE structure indicates success. NULL indicates failure.

Remarks

Alternate settings are used to supply alternate interfaces that can be selected by user software. For a device with no alternate settings, use a value of 0.

This function is defined in the Mousedrv.cpp file.

See Also

GetDeviceInfo


GetDescriptor

This function sends a GET_DESCRIPTOR request to a USB device.

Syntax

USB_TRANSFER GetDescriptor(USB_HANDLE hDevice, LPTRANSFER_NOTIFY_ROUTINE lpStartAddress,
LPVOID lpvNotifyParameter, DWORD dwFlags, UCHAR bType,
UCHAR bIndex, WORD wLanguage, WORD wLength, LPVOID lpvBuffer);

Parameters

hDevice
[IN] Handle to a USB device.
lpStartAddress
[IN] Pointer to the address, which may be NULL, of a callback routine.
lpvNotifyParameter
[IN] Pointer to the parameter to pass to a callback routine.
dwFlags
[IN] Either of the values USB_NO_WAIT or 0.
bType
[IN] The descriptor type, one of the values USB_DEVICE_DESCRIPTOR_TYPE, USB_CONFIGURATION_DESCRIPTOR_TYPE, USB_STRING_DESCRIPTOR_TYPE, or a vendor-specific value.
bIndex
[IN] Index within a descriptor.
wLanguage
[IN] Specifies a language IDENTIFIER for string descriptors, 0 for others.
wLength
[IN] Specifies the size of the buffer.
lpvBuffer
[IN] Pointer to a buffer for descriptor data.

Remarks

This function initiates a control transfer to a USB device requesting device descriptor information. The device returns the contents of the device descriptor, starting at the index specified.

This function is defined in the Mousedrv.cpp file.

See Also

AbortTransfer, GetTransferStatus, IsTransferComplete, SetDescriptor


GetDeviceInfo

This function gets a pointer to a device information structure.

Syntax

LPCUSB_DEVICE GetDeviceInfo(USB_HANDLE hDevice);

Parameters

hDevice
[IN] Handle to a USB device.

Return Values

Returns a pointer to the USB_DEVICE structure for a device.

Remarks

This function is defined in the Mousedrv.cpp file.


GetFrameLength

This function gets a current USB frame length.

Syntax

BOOL GetFrameLength(USB_HANDLE hDevice,
LPUSHORT lpuFrameLength);

Parameters

hDevice
[IN] Handle to a USB device.
lpuFrameLength
[OUT] Pointer to the current frame length.

Return Values

TRUE indicates success. FALSE indicates failure. A bug in the implementation of this function in Windows CE 2.10 causes this function to always return FALSE.

Remarks

This function is defined in the Mousedrv.cpp file.


GetFrameNumber

This function gets a current USB frame number.

Syntax

BOOL GetFrameNumber(USB_HANDLE hDevice,
LPDWORD lpdwFrameNumber);

Parameters

hDevice
[IN] Handle to a USB device.
lpdwFrameNumber
[OUT] Pointer to a frame number.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function is defined in the Mousedrv.cpp file.


GetInterface

This function sends a request to a USB device for information about alternate device settings.

Syntax

USB_TRANSFER GetInterface(USB_HANDLE hDevice, LPTRANSFER_NOTIFY_ROUTINE lpStartAddress,
LPVOID lpvNotifyParameter, DWORD dwFlags, UCHAR bInterfaceNumber, PUCHAR lpbAlternateSetting);

Parameters

hDevice
[IN] Handle to a USB device.
lpStartAddress
[IN] Non-null pointer to a pointer to a callback routine.
lpvNotifyParameter
[IN] Pointer to a parameter to pass to the callback routine.
dwFlags
[IN] Specifies either of the values USB_NO_WAIT or 0.
bInterfaceNumber
[IN] Specifies the interface number.
lpbAlternateSetting
[OUT] Filled in with current alternate setting value.

Return Values

A USB_TRANSFER handle indicates success. NULL indicates failure.

Remarks

This function initiates a control transfer to a USB device, requesting the alternate setting selected for the specified interface.

This function is defined in the Mousedrv.cpp file.

See Also

AbortTransfer, GetTransferStatus, IsTransferComplete, SetInterface


GetIsochResults

This function gets the status of an active isochronous transfer.

Syntax

BOOL GetIsochResults(USB_TRANSFER hTransfer, DWORD cFrames, LPDWORD lpdwBytesTransferred, LPDWORD lpdwErrors);

Parameters

hTransfer
[IN] Handle to an isochronous transfer.
cFrames
[IN] Specifies the number of frames to return results for.
lpdwBytesTransferred
[OUT] Pointer to an array of lengths. This pointer may be NULL, in which case this function does not report bytes-transferred information.
lpdwErrors
[OUT] Pointer to an array of error values. This pointer may be NULL, in which case this function does not report error value information.

Return Values

Returns TRUE if hTransfer points to a completed isochronous transfer, FALSE otherwise.

Remarks

The supplied arrays are filled out with the error values and amounts of data transferred for each frame. There may have been data transferred on a frame, even if an error is returned.

This function is defined in the Mousedrv.cpp file.


GetPrinterInfo

This function is used to obtain information about printers, such as the name of the printer or whether the printer can print in color.

Syntax

DWORD WINAPI GetPrinterInfo(HANDLE hPrint, DWORD dwOption, PVOID pBuff, PDWORD pBuffLen);

Parameters

[IN] hPrint
Handle obtained from the PrinterOpen function.
[IN] dwOption
Specifies the printer option to retrieve. The following options are available in Windows CE 2.10 and later:
PRINTER_ID
Retrieves the name of the printer. The pBuff parameter must point to a string previously allocated by the calling application. If pBuff is NULL, this function returns ERROR_SUCCESS, and pBuffLen contains the number of characters needed to store the printer name, including the terminating null character. If pBuffLen is NULL, this function returns ERROR_INVALID_PARAMETER. If pBuffLen is not long enough to hold the name of the printer, this function returns ERROR_MORE_DATA along with the correct number of characters needed, including the terminating null character in pBuffLen.
PRINTER_PEN
Retrieves the color or black-and-white capabilities of the ink cartridge currently in an InkJet printer. The pBuff parameter points to a DWORD containing one of the values PEN_BLACK or PEN_COLOR. These values are declared in the Prnport.h header file.
[OUT] pBuff
If pBuff is NULL, this function returns the size of the requested information in the pBufLen parameter, including any terminating null characters. If pBuff is not NULL, this function returns the requested information in the location pointed to by pBuff.
[IN/OUT] pBuffLen
On output, pBufLen contains the size of the requested data. If pBufLen is NULL, this function returns ERROR_INVALID_PARAMETER.

Return values

ERROR_SUCCESS indicates success. One of the following values indicates failure:

ERROR_INVALID_PARAMETER
ERROR_DEVICE_NOT_READY
ERROR_OPENING_PRINT_DEVICE
ERROR_NOT_SUPPORTED
ERROR_MORE_DATA

Remarks

In Windows CE 2.10, This function supports only printers that connect by means of the parallel port.


GetSerialObject

This function retrieves the list of serial devices.

Syntax

PDEVICE_LIST GetSerialObject(void);

Return Values

The DEVICE_LIST structure that contains information about the devices supported in this implementation.

Remarks

This function is part of the implementation of the PDDs of serial port drivers. A single function driver would contain only one element in its device list. Drivers which integrate multiple PDDs in one DLL should create a device element for each PDD instance. This function is declared in the Serhw.h header file, and is available in Windows CE version 1.0 and later.


GetStatus

This function sends a GET_STATUS request to a USB device.

Syntax

USB_TRANSFER GetStatus(USB_HANDLE hDevice, LPTRANSFER_NOTIFY_ROUTINE lpStartAddress,
LPVOID lpvNotifyParameter, DWORD dwFlags, UCHAR bIndex,
LPWORD lpwStatus);

Parameters

hDevice
[IN] Handle to a USB device.
lpStartAddress
[IN] Pointer to a pointer to a callback routine, which may be NULL.
lpvNotifyParameter
[IN] Pointer to the parameter to pass to a callback routine.
dwFlags
[IN] Specify USB_NO_WAIT or 0, plus one of the following:
USB_SEND_TO_DEVICE
Request for status of the device.
USB_SEND_TO_INTERFACE
Request for status of the interface.
USB_SEND_TO_ENDPOINT
Request for status of the endpoint.
bIndex
[IN] Specifies 0 for DEVICE, or interface or endpoint number.
lpwStatus
[OUT] Filled in with the device’s status.

Return Values

A USB_TRANSFER handle indicates success. NULL indicates failure.

Remarks

This function initiates a control transfer to a USB device requesting device, interface, or endpoint status.

This function is defined in the Mousedrv.cpp file.

See Also

AbortTransfer, GetStatus, GetTransferStatus, IsTransferComplete


GetTransferError

This function returns an error value associated with a USB transfer.

Syntax

BOOL GetTransferError(USB_TRANSFER hTransfer,
LPDWORD lpdwError);

Parameters

hTransfer
[IN] Handle to a USB transfer.
lpdwError
[OUT] Filled in with an error value.

Return Values

Returns FALSE if hTransfer does not point to a valid USB_TRANSFER structure. Otherwise, this function returns TRUE, and any error values associated with the transfer are stored in lpdwError.

Remarks

Transfer error values are declared in the Usbtypes.h header file. If the transfer has not been completed, lpdwError is set to USB_NOT_COMPLETE_ERROR.

This function is defined in the Mousedrv.cpp file.


GetTransferStatus

This function gets the status of an active transfer.

Syntax

BOOL GetTransferStatus(USB_TRANSFER hTransfer,
LPDWORD lpdwBytesTransferred, LPDWORD lpdwError);

Parameters

hTransfer
[IN] Handle to a USB transfer.
lpdwBytesTransferred
[OUT] Pointer to the number of of bytes transferred. The pointer may be NULL, in which case this function does not report the number of bytes transferred.
lpdwError
[OUT] Pointer to a value containing error values for the transfer or the value USB_NO_ERROR. The pointer may be NULL, in which case this function does not report the error value.

Return Values

Returns TRUE if hTransfer points to a valid USB_TRANSFER structure and FALSE otherwise.

Remarks

This function is used to get the results of a completed transfer. Even transfers that have errors may have valid data indicated.

This function is defined in the Mousedrv.cpp file.


GetUSBDVersion

This function returns the version number of the USBD interface present on a Windows CE–based platform.

Syntax

VOID GetUSBDVersion(LPDWORD lpdwMajorVersion,
LPDWORD lpdwMinorVersion);

Parameters

lpdwMajorVersion
[OUT] Pointer to the USBD major version number.
lpdwMinorVersion
[OUT] Pointer to the USBD minor version number.

Return Values

None.

Remarks

This function can be used to determine the current version of the USBD interface. USBD interface version 1.0 corresponds to Windows CE 2.10. USBD interface version 1.1 corresponds to Windows CE 2.11 and later.

This function is defined in the Mousedrv.cpp file.


HWClearBreak

This function clears a RS-232 line break condition.

Syntax

VOID HWClearBreak(PVOID pContext);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.

Return Values

None.

Remarks

This function supports the implementation of the PDDs of serial port drivers. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit


HWClearDTR

This function clears the Data Terminal Ready (DTR) signal.

Syntax

VOID HWClearDTR(PVOID pContext);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.

Return Values

None.

Remarks

This function supports the implementation of the PDDs of serial port drivers.

This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit, HWSetDTR


HWClearRTS

This function clears the Request to Send (RTS) signal.

Syntax

VOID HWClearRTS(PVOID pContext);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.

Return Values

None.

Remarks

This function supports the implementation of the PDDs of serial port drivers. This function is declared in the Serhw.h and header file is available in Windows CE version 1.0 and later.

See Also

HWInit, HWSetRTS


HWClose

This function closes the device initialized by the HWInit function.

Syntax

ULONG HWClose(PVOID pContext);

Parameters

pContext
Pointer to a context structure returned by HWInit that contains implementation-specific data describing the hardware device.

Return Values

Zero indicates success.

Remarks

This function supports the implementation of the PDDs of serial port drivers. This function is decared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit, HWOpen


HWDeinit

This function is called by the MDD layer to de-initialize the hardware when a device driver is unloaded.

Syntax

BOOL HWDeinit(PVOID pContext);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function is called when the device is no longer needed. It is never called for built-in devices. Rather, it is called for PC Card devices when the card is removed.

This function supports the implementation of the PDDs of serial port drivers. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit


HWDisableIR

This function disables the infrared (IR) serial interface, returning the port to standard RS-232 serial if it supports both modes.

Syntax

BOOL HWDisableIR(PVOID pContext);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.

Return Values

TRUE indicates success. FALSE indicates failure. If an error occurs, the caller can return the error using GetLastError.

Remarks

This function supports the implementation of the PDDs of serial port drivers. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit, HWEnableIR


HWEnableIR

This function enables the infrared (IR) serial interface.

Syntax

BOOL HWEnableIR(PVOID pContext, ULONG BaudRate);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.
Baud
Specifies the baud to set.

Return Values

TRUE indicates success. FALSE indicates failure. If an error occurs, the caller can return the error using GetLastError.

Remarks

This function sets the device into IR mode. It returns NULL if the device does not support IR mode.

This function supports the implementation of the PDDs of serial port drivers. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit, HWDisableIR


HWGetBytes

This function gets a number of bytes from the device; the number may be 0.

Syntax

ULONG HWGetBytes(PVOID pContext, PUCHAR pTargetBuffer,
PULONG pByteNumber);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.
pTargetBuffer
Pointer to the target buffer in which to put the data.
pByteNumber
Pointer to, on entry, the maximum number of bytes to read. On exit, the number of bytes read.

Return Values

The return value is the number of bytes dropped by the hardware.

Remarks

This function gets several characters from the hardware receive buffer and puts them into the location pointed to by the second parameter. If there are no characters available for reading, this function returns immediately. This function is called in response to a receive interrupt indication from the HWGetIntrType function.

This function supports the implementation of the PDDs of serial port drivers. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit, HWGetIntrType


HWGetCommProperties

This function retrieves the current properties of the communications device.

Syntax

VOID HWGetCommProperties(PVOID pContext,
LPCOMMPROP pCommProp);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.
pCommProp
Pointer to a COMMPROP structure to hold the communications property information.

Return Values

None.

Remarks

This function supports the implementation of the PDDs of serial port drivers. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit, COM_IOControl


HWGetIntrType

This function returns the current interrupt type.

Syntax

INTERRUPT_TYPE HWGetIntrType(PVOID pContext);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.

Return Values

The interrupt type; one of the following:

  • INTR_NONE
  • INTR_LINE
  • INTR_RX
  • INTR_TX
  • INTR_MODEM

Interrupt types are declared in the Serhw.h header file.

Remarks

This function is called by the MDD to determine what type of interrupt occurred.

This function supports the implementation of the PDDs of serial port drivers. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit, HWGetBytes, HWTxIntrHandler


HWGetModemStatus

This function retrieves the modem status.

Syntax

VOID HWGetModemStatus(PVOID pContext, PULONG pModemStatus);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.
pModemStatus
[OUT] Pointer to a ULONG value in which this function stores the modem status.

Return Values

None. Values stored in pModemStatus are the same as the Windows CE GetCommModemStatus function.

Remarks

This function supports the implementation of the PDDs of serial port drivers. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit


HWGetRxBufferSize

This function returns the maximum number of bytes that the hardware buffer can hold, not counting the padding, stop, and start bits.

Syntax

ULONG HWGetRxBufferSize(PVOID pContext);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.

Return Values

Returns the number of bytes in the hardware receive queue.

Remarks

This function supports the implementation of the PDDs of serial port drivers. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit


HWGetRxStart

This function returns the start of the hardware receive buffer.

Syntax

PVOID HWGetRxStart(PVOID pContext);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device. This parameter is passed to the InterruptInitialize function in the hardware abstraction layer (HAL). It was originally intended for the interrupt service routine to handle receive characters in a fast path, but currently is unused.

Return Values

Returns a pointer to the start of the device receive buffer.

Remarks

This function supports the implementation of the PDDs of serial port drivers. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit


HWGetStatus

This function specifies the hardware status API.

Syntax

ULONG HWGetStatus(PVOID pContext, LPCOMSTAT lpStat);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.
lpStat
Pointer to an LPCOMMSTAT structure to hold status.

Return Values

Zero indicates success. A value of –1 indicates failure.

Remarks

See ClearCommError for a description of lpStat.

This function supports the implementation of the PDD of serial port drivers. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit


HWInit

This function initializes a serial device.

Syntax

PVOID HWInit(ULONG Identifier, PVOID pMDDContext);

Parameters

Identifier
An LPCWSTR that contains the registry key of the active device.
pMDDContext
Pointer to a device context used on all function calls to the device driver.

Return Values

A pointer to a context structure that contains implementation-specific data describing the hardware device.

Remarks

This function sets information controlled by the user, such as line control and baud rate. It can also initialize events and interrupts, indirectly managing the initializing of hardware buffers. It is exported only to the MDD, and it is called only once when the device driver is loaded in response to a call to the COM_Init function. For built-in devices, this occurs at boot time. For PC Cards, this occurs when a card is inserted.

This function is part of the implementation of the PDDs of serial port drivers. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.


HWIoctl

This function is the device I/O control routine.

Syntax

BOOL HWIoctl(DWORD dwOpenData, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
PDWORD pdwActualOut);

Parameters

dwOpenData
Specifies a value returned from a call to the COM_Open function.
dwCode
Specifies an I\O control code to be performed.
pBufIn
Pointer to the data input to the device.
dwLenIn
Specifies the number of bytes being passed in.
pBufOut
Pointer to the output data from the device.
dwLenOut
Specifies the maximum number of bytes to receive from a device.
pdwActualOut
Pointer to the actual number of bytes received from a device.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

The MDD passes any unrecognized I/O Control codes through to this function. OEMs can implement custom I/O control codes for whatever purposes they need.

This function supports the implementation of the PDDs of serial port drivers. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.


HWOpen

This function is called by the MDD layer to open the serial device.

Syntax

BOOL HWOpen(PVOID pContext);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function applies power to the serial hardware. This function is part of the implementation of the PDDs of the serial port drivers. This function is defined in the header file SerHW.h, and is available in Windows CE version 1.0 and later.

See Also

HWInit


HWPowerOff

This function is called by the model device driver to notify the platform-dependent driver that the platform is about to enter suspend mode.

Syntax

BOOL HWPowerOff(PVOID pContext);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function is called when the device is turned off. Because this call is without standard process/thread context, take care in writing this function. No DLLs or system calls, such as Sleep, can be used. This function saves its state to local storage, and then returns. As with all power-down handlers, this function cannot call functions in other DLLs, memory allocators, debugging output functions, or do anything that could cause a page fault.

This function is part of the implementation of the PDDs of serial port drivers. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit


HWPowerOn

This function is called by the model device driver to notify the platform-dependent driver that the platform is resuming from suspend mode.

Syntax

BOOL HWPowerOn(PVOID pContext);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function is called when the device enters a power-up state. Since this call is without standard process/thread context, take care in writing this function. No DLLs or system calls, such as Sleep, can be used. This function restores its state from local storage, and then returns.

This function supports the implementation of the PDDs of serial port drivers. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit


HWPurgeComm

This function purges the communications device.

Syntax

VOID HWPurgeComm(PVOID pContext, DWORD fdwAction);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.
fdwAction
One of the following values:
  • PURGE_TXABORT
  • PURGE_RXABORT
  • PURGE_TX_CLEAR
  • PURGE_RXCLEAR

Return Values

None.

Remarks

This function purges the serial device according to Win32 semantics for the following:

  • PURGE_TXABORT
  • PURGE_RXABORT
  • PURGE_TXCLEAR
  • PURGE_RXCLEAR

This function is part of the implementation of the PDDs of serial port drivers. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit


HWPutBytes

This function is called by a driver to write bytes to hardware.

Syntax

ULONG HWPutBytes(PVOID pContext, PUCHAR pSrc,
ULONG NumberOfBytes, PULONG pBytesSent);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.
pSrc
Pointer to bytes to be sent.
NumberOfBytes
Specifies the number of bytes to be sent.
pBytesSent
Pointer to the actual number of bytes written.

Return Values

This function returns 0 or the minimum number of milliseconds before the MDD layer should call again. This is used if the device does not support interrupt-based indications of changes in the status of hardware flow-control lines. The MDD layer calls again to see if the flow-control condition has been removed.

Remarks

This function supports the implementation of the PDDs of serial port drivers. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit


HWReset

This function resets the hardware API.

Syntax

ULONG HWReset(PVOID pContext);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.

Return Values

Resets the COMSTAT status used by the HWGetStatus function.

Remarks

This function supports the implementation of the PDDs of serial port drivers. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit


HWSetBreak

This function sets the line break condition on the transmit (TX) line.

Syntax

VOID HWSetBreak(PVOID pContext);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.

Return Values

None.

Remarks

This function supports the implementation of the PDDs of serial port drivers. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later. The output line should output 0s—typically, by locking the line at a positive voltage—until the HWClearBreak functionis called.

See Also

HWInit, HWClearBreak


HWSetCommTimeouts

This function sets the communications time-outs in response to a call to the SetCommTimeouts function.

Syntax

BOOL HWSetCommTimeouts(PVOID pContext,
LPCOMMTIMEOUTS lpCommTO);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.
lpCommTO
Pointer to a CommTimeouts structure.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function supports the implementation of the PDDs of serial port drivers. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later. Typically, the MDD keeps track of communications time-outs. The PDD usually does not need to act on time-outs.

See Also

HWInit


HWSetDCB

This function sets the device control block.

Syntax

BOOL HWSetDCB(PVOID pContext, LPDCB pDCB);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.
pDCB
Pointer to the device control block to set.

Return Values

TRUE indicates success. FALSE indicates failure. If an error occurs, the caller can return the error using GetLastError.

Remarks

This function is called by the MDD after the user has called the SetCommState function.

This function supports the implementation of the Serial Port Drivers PDD. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit


HWSetDTR

This function sets the Data Terminal Ready (DTR) signal.

Syntax

VOID HWSetDTR(PVOID pContext);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.

Return Values

None.

Remarks

This function sets the DTR signal. This function supports the implementation of the Serial Port Drivers PDD. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit, HWClearDTR


HWSetRTS

This function sets the Request to Send (RTS) signal.

Syntax

VOID HWSetRTS(PVOID pContext);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.

Return Values

None.

Remarks

This function supports the implementation of the Serial Port Drivers PDD. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit, HWClearRTS


HWTxIntrHandler

This function handles the TX interrupt.

Syntax

VOID HWTxIntrHandler(PVOID pContext);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.

Remarks

This function clears the transmit interrupt status bit in the hardware CSR and performs any internal bookkeeping necessary so that the HWPutBytes function can send data. It is called when the driver detects a transmit interrupt, as set by the HWGetIntrType function. This function supports the implementation of the Serial Port Drivers PDD. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit, HWGetIntrType


HWXmitComChar

This function transmits a single character.

Syntax

BOOL HWXmitComChar(PVOID pContext, UCHAR ComChar);

Parameters

pContext
Pointer to a context structure returned by the HWInit function that contains implementation-specific data describing the hardware device.
ComChar
Specifies the character to transmit.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

The PDD transmits the specified character as soon as possible, before any buffered data. This is called by the user through the TransmitComChar function or by the MDD layer, usually for XON/XOFF processing.

This function supports the implementation of the Serial Port Drivers PDD. This function is declared in the Serhw.h header file and is available in Windows CE version 1.0 and later.

See Also

HWInit


InitializeListHead

This function initializes any doubly-linked, driver-managed interlocked queue or doubly-linked, driver-maintained list.

At a Glance

Header file: | Ntcompat.h
Windows CE versions: | 2.0 and later

Syntax

VOID InitializeListHead(IN PLIST_ENTRY ListHead);

Parameters

ListHead
Pointer to the driver-allocated storage for the head of the interlocked queue or list. For an interlocked queue, the storage must be resident, and the driver must also provide storage for a spin lock.

Remarks

This function must be called from the DriverEntry function if a driver sets up internal interlocked queues for IRPs or manages internal linked lists.

The ListHead of type LIST_ENTRY is doubly linked. Entries in an interlocked queue can be queued and dequeued by calling the ExInterlockedInsert XXX List and ExInterlockedRemoveHeadList functions. Entries can be inserted into and removed from a driver-maintained list with Insert XXX List and Remove XXX List.

For an interlocked queue, a driver must provide resident storage in the device extension of a driver-created device object, in the controller extension of a driver-created controller object, or in nonpaged pool allocated by the driver. The driver must also provide storage for a spin lock, which must be initialized with the KeInitializeSpinLock function before the driver’s initial call to the ExInterlocked XXX function with the spin lock.

For a driver-maintained list, the driver must synchronize access to the list so that it is impossible for any two routines to be inserting and/or removing entries from the list simultaneously in symmetric multiprocessing devices. Consequently, most drivers use the ExInterlocked XXX functions to manage the necessary synchronization, rather than setting up a driver-managed list, which is likely to require spin-lock protection, anyway.

A driver that calls this function must be running at IRQL PASSIVE_LEVEL.


InsertHeadList

This function inserts an entry at the head of a doubly-linked, driver-managed list.

At a Glance

Header file: | Ntcompat.h
Windows CE versions: | 2.0 and later

Syntax

VOID InsertHeadList(IN PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry);

Parameters

ListHead
Pointer to the driver-allocated storage for the head of the list.

When this parameter is of type LIST_ENTRY, it is doubly linked.

Entry
Pointer to an entry to be inserted in the list.

Remarks

A driver that calls this function can be running at IRQL >= DISPATCH_LEVEL only if the caller-allocated storage for ListHead is resident and only if pointers to every list entry remain valid at IRQL >= DISPATCH_LEVEL as well.

See Also

InitializeListHead, InsertTailList, IsListEmpty, RemoveHeadList, RemoveTailList


InsertTailList

This function inserts an entry at the tail of a doubly-linked, driver-managed list.

At a Glance

Header file: | Ntcompat.h
Windows CE versions: | 2.0 and later

Syntax

VOID InsertTailList(IN PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry);

Parameters

ListHead
Pointer to the driver-allocated storage for the head of the list.

The ListHead of type LIST_ENTRY is doubly linked.

Entry
Pointer to an entry to be inserted in the list.

Remarks

A driver that calls this function can be running at IRQL >= DISPATCH_LEVEL only if the caller-allocated storage for ListHead is resident and only if pointers to every list entry remain valid at IRQL >= DISPATCH_LEVEL as well.

See Also

InitializeListHead, InsertHeadList, IsListEmpty, RemoveHeadList, RemoveTailList


IsDefaultPipeHalted

This function checks if the default pipe to a USB device is halted.

Syntax

BOOL IsDefaultPipeHalted(USB_HANDLE hDevice, LPBOOL lpbHalted);

Parameters

hDevice
[IN] Handle to a USB device.
lpbHalted
[OUT] Pointer to a BOOL containing TRUE if the pipe is halted, FALSE otherwise.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function is only available in USBD interface version 1.1 or later.

See Also

ResetDefaultPipe, GetUSBDVersion


IsListEmpty

This function indicates whether or not a doubly-linked, driver-maintained list is empty.

At a Glance

Header file: | Ntcompat.h
Windows CE versions: | 2.0 and later

Syntax

BOOLEAN IsListEmpty(IN PLIST_ENTRY ListHead);

Parameters

ListHead
Pointer to the driver-allocated storage for the head of the list.

When this parameter is of type LIST_ENTRY, it is doubly linked.

Return Values

Returns TRUE if there are currently no entries in the list.

Remarks

A driver that calls this function can be running at IRQL >= DISPATCH_LEVEL only if the caller-allocated storage for ListHead is resident and only if pointers to every list entry remain valid at IRQL >= DISPATCH_LEVEL as well.

See Also

InitializeListHead, RemoveHeadList, RemoveTailList, RemoveEntryList


IsPipeHalted

This function checks if a USB pipe is in a halted state.

Syntax

BOOL IsPipeHalted(USB_PIPE hPipe, LPBOOL lpbHalted);

Parameters

hPipe
[IN] Handle to a USB pipe.
lpbHalted
[OUT] Pointer to a BOOL containing TRUE if the pipe is halted, FALSE otherwise.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function may be used to determine whether or not a pipe is halted.

This function is defined in the Mousedrv.cpp file.


IssueBulkTransfer

This function initiates a bulk transfer with a USB device.

Syntax

USB_TRANSFER IssueBulkTransfer(USB_PIPE hPipe, LPTRANSFER_NOTIFY_ROUTINE lpStartAddress,
LPVOID lpvNotifyParameter, DWORD dwFlags, DWORD dwBufferSize, LPVOID lpvBuffer, ULONG uBufferPhysicalAddress);

Parameters

hPipe
[IN] Handle to an open USB pipe.
lpStartAddress
[IN] Pointer to the address, which may be NULL, of a callback routine.
lpvNotifyParameter
[IN] Pointer to the parameter to pass to a callback routine.
dwFlags
[IN] Flags for the transfer. These are declared in the Usbtypes.h header file.
dwBufferSize
[IN] Specifies the size of the data buffer, in bytes.
lpvBuffer
[IN/OUT] Pointer to the data buffer. If a physical buffer address is specified, this must contain the virtual address of the buffer.
uBufferPhysicalAddress
[IN/OUT] Specifies the physical address, which may be NULL, of the data buffer.

Return Values

A USB_TRANSFER handle indicates success. NULL indicates failure.

Remarks

This function initiates a bulk transfer to a USB device on the specified endpoint.

This function is defined in the Mousedrv.cpp file.

See Also

AbortTransfer, GetTransferStatus, IsTransferComplete


IssueControlTransfer

This function initiates a control transfer with a USB device.

Syntax

USB_TRANSFER IssueControlTransfer(USB_PIPE hPipe, LPTRANSFER_NOTIFY_ROUTINE lpStartAddress,
LPVOID lpvNotifyParameter, DWORD dwFlags, LPCVOID lpvControlHeader, DWORD dwBufferSize, LPVOID lpvBuffer, ULONG uBufferPhysicalAddress);

Parameters

hPipe
[IN] Handle to an open USB pipe.
lpStartAddress
[IN] Pointer to the address, which may be NULL, of a callback routine.
lpvNotifyParameter
[IN] Pointer to the parameter to pass to a callback routine.
dwFlags
[IN] Flags for the transfer. These are declared in the Usbtypes.h header file.
lpvControlHeader
[IN] Pointer to control header (8 bytes).
dwBufferSize
[IN] Specifies the size of the data buffer.
lpvBuffer
[IN] Pointer to a data buffer. If a physical buffer address is specified, this must contain the virtual address of the buffer.
uBufferPhysicalAddress
[IN] Specifies the physical address, which may be NULL, of the data buffer.

Return Values

A USB_TRANSFER handle indicates success. NULL indicates failure.

Remarks

This function initiates a control transfer to a USB device on the specified endpoint.

This function is defined in the Mousedrv.cpp file.

See Also

AbortTransfer, GetTransferStatus, IsTransferComplete


IssueInterruptTransfer

This function initiates an interrupt transfer with a USB device.

Syntax

USB_TRANSFER IssueInterruptTransfer(USB_PIPE hPipe, LPTRANSFER_NOTIFY_ROUTINE lpStartAddress,
LPVOID lpvNotifyParameter, DWORD dwFlags, DWORD dwBufferSize, LPVOID lpvBuffer, ULONG uBufferPhysicalAddress);

Parameters

hPipe
[IN] Handle to an open USB pipe.
lpStartAddress
[IN] Pointer to the address, which may be NULL, of a callback routine.
lpvNotifyParameter
[IN] Parameter to pass to the callback routine.
dwFlags
[IN] Flags for the transfer. These are declared in the Usbtypes.h header file.
dwBufferSize
[IN] Specifies the size of data buffer.
lpvBuffer
[IN] Pointer to the data buffer. If the physical buffer address is specified, this must contain the virtual address of the buffer.
uBufferPhysicalAddress
[IN] Specifies the physical address, which may be NULL, of the data buffer.

Return Values

A USB_TRANSFER handle indicates success. NULL indicates failure.

Remarks

This function initiates an interrupt transfer to a USB device on the specified endpoint.

This function is defined in the Mousedrv.cpp file.

See Also

AbortTransfer, GetTransferStatus, IsTransferComplete


IssueIsochTransfer

This function initiates an isochronous transfer with a USB device.

Syntax

USB_TRANSFER IssueIsochTransfer(USB_PIPE hPipe, LPTRANSFER_NOTIFY_ROUTINE lpStartAddress,
LPVOID lpvNotifyParameter, DWORD dwFlags, DWORD dwStartingFrame, DWORD dwFrames, LPCDWORD lpdwLengths, LPVOID lpvBuffer,
ULONG uBufferPhysicalAddress);

Parameters

hPipe
[IN] Handle to an open USB pipe.
lpStartAddress
[IN] Pointer to the address, which may be NULL, of a callback routine.
lpvNotifyParameter
[IN] Pointer to the parameter to pass to a callback routine.
dwFlags
[IN] Flags for the transfer. These are declared in the Usbtypes.h header file. Some flags are specific to isochronous transfers. USB_START_ISOCH_ASAP starts transfer as soon as possible, instead of specifying a starting frame. USB_COMPRESS_ISOCH guarantees, for IN transfers, that data is copied contiguously to the user buffer, instead of being fragmented if the amount of data is less than the maximum requested for a particular frame.
dwStartingFrame
[IN] Specifies the frame number on which transfer starts.
dwFrames
[IN] Specifies the number of frames in transfer.
lpdwLengths
[IN/OUT] Pointer to an array of lengths, one entry per frame.
lpvBuffer
[IN/OUT] Pointer to a data buffer. If a physical buffer address is specified, this must contain the virtual address of the buffer.
uBufferPhysicalAddress
[IN/OUT] Specifies the physical address, which may be NULL, of the data buffer.

Return Values

A USB_TRANSFER handle indicates success. NULL indicates failure.

Remarks

This function initiates an isochronous transfer to a USB device on the specified endpoint. Since isochronous transfers must be executed continuously, a sequence of buffers is provided, one of which is transferred for each frame. There is no limit on the number of buffers that may be provided, though each one must be less than or equal to the maximum packet size for the endpoint.

This function is defined in the Mousedrv.cpp file.

See Also

AbortTransfer, GetIsochResults, GetTransferStatus, IsTransferComplete


IssueVendorTransfer

This function sends a vendor-specific control transfer to a USB device.

Syntax

USB_TRANSFER IssueVendorTransfer(USB_HANDLE hDevice, LPTRANSFER_NOTIFY_ROUTINE lpStartAddress,
LPVOID lpvNotifyParameter, DWORD dwFlags, LPCUSB_DEVICE_REQUEST lpControlHeader, LPVOID lpvBuffer, ULONG uBufferPhysicalAddress);

Parameters

hDevice
[IN] Handle to a USB device.
lpStartAddress
[IN] Pointer to the address, which may be NULL, of a callback routine.
lpvNotifyParameter
[IN] Pointer to the parameter to pass to a callback routine.
dwFlags
[IN] Flags for the transfer. These are declared in the Usbtypes.h header file.
lpControlHeader
[IN] Pointer to a device request header.
lpvBuffer
[IN] Data buffer. If a physical buffer address is specified, this must contain the virtual address of the buffer.
uBufferPhysicalAddress
[IN] Specifies the physical address, which may be NULL, of the data buffer.

Return Values

A USB_TRANSFER handle indicates success. NULL indicates failure.

Remarks

This function initiates a control transfer to a USB device on the default endpoint (0). This function is intended for vendor-specific transfers. For standard transfers, use a corresponding function, such as GetInterface or SetInterface.

This function is defined in the Mousedrv.cpp file.

See Also

AbortTransfer, GetTransferStatus, IsTransferComplete


IsTransferComplete

This function checks whether a transfer has completed.

Syntax

BOOL IsTransferComplete(USB_TRANSFER hTransfer);

Parameters

hTransfer
[IN] Handle to a USB transfer.

Return Values

TRUE indicates that a transfer has completed. FALSE indicates that a transfer has not completed.

Remarks

This function is defined in the Mousedrv.cpp file.


KdBreakPoint

This function is the kernel debug breakpoint routine.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID KdBreakPoint();

Remarks

This function is identical to the KdBreakPoint function in Windows NT.


KdPrint

This function is the kernel debug print routine.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID KdPrint(LPSTR *lpszString);

Remarks

This function is identical to the KdPrint function in Windows NT.


KeybdDriverGetInfo

This function gives information about the keyboard and driver.

Syntax

BOOL KeybdDriverGetInfo(INT iKeybdId, INT iIndex, LPVOID lpOutput);

Parameters

iKeybdId
Identifier of the keyboard from which to get the information.
iIndex
Identifier of the information to retrieve.
lpOutput
Pointer to the output buffer.

Return Values

TRUE indicates success. FALSE indicates failure. Extended error information is available through GetLastError.

Remarks

This function must be re-entrant, since it is exposed by the input system through the KeybdGetDeviceInfo function and may be called by multiple threads.

This function is defined in the Keybdmdd.cpp file.


KeybdDriverInitialize

This function does one-time-only keyboard driver initialization.

Syntax

void KeybdDriverInitialize(PFN_KEYBD_EVENT_CALLBACK pfnKeybdEventCallback);

Parameters

pfnKeybdEventCallback
Pointer to a function used as the callback into the input system.

Return Values

TRUE indicates success. FALSE indicates failure. Extended error information is available through GetLastError.

Remarks

This function should call the KeybdPdd_InitializeDriver function, then start a driver interrupt service thread.

This function is defined in the Keybdmdd.cpp file.


KeybdDriverInitStates

This function initializes the virtual key state and driver specific state.

Syntax

BOOL KeybdDriverInitStates(INT iKeybdId, KEY_STATE KeyState,
void *pKeybdDeviceToUnicodeState);

Parameters

iKeybdId
Identifier of the keyboard for which to initialize keystate data.
KeyState
Specifies the key state to initialize.
pKeybdDeviceToUnicodeState
Specifies the keyboard-specific state to initialize.

Remarks

After calling the KeybdDriverGetInfo function and allocating its required memory, the input system calls this function to enable the driver to initialize the memory.

The pKeybdDriverToUnicodeState parameter is a pointer to a block of memory of at least cbToUnicodeState bytes, as reported by the KeybdDriverGetInfo function in the KBDI_VKEY_TO_UNICODE_INFO structure. If cbToUnicodeState is reported as 0, this parameter may be NULL.

This function must be re-entrant, since it is exposed by the input system through the KeybdInitStates function and may be called by multiple threads.

This function is defined in the Keybdmdd.cpp file.

See Also

KeybdDriverGetInfo


KeybdDriverPowerHandler

This function handles system power-state change notifications.

Syntax

void KeybdDriverPowerHandler(BOOL bOff);

Parameters

bOff
Boolean. TRUE if the system is being turned off. FALSE if the system is being turned on.

Remarks

This function is called in a kernel context and should not make any system calls or do anything that might cause a DLL to be loaded.

This function resets the autorepeat state and calls the KeybdPdd_PowerHandler function.

This function is defined in the Keybdmdd.cpp file.


KeybdDriverSetMode

This function sets mode information for the keyboard device.

Syntax

BOOL KeybdDriverSetMode(INT iKeybdId, INT iIndex, LPVOID lpInput);

Parameters

iKeybdId
Identifier of the keyboard for which to set the information.
iIndex
Identifier of information to set.
lpInput
Pointer to an input buffer.

Return Values

TRUE indicates success. FALSE indicates failure. Extended error information is available through GetLastError.

Remarks

This function is defined in the Keybdmdd.cpp file.

See Also

KeybdDriverGetInfo


KeybdDriverVKeyToUnicode

This function generates the appropriate Unicode characters and shift state flags for a specified virtual key, key state array, and driver state.

Syntax

UINT32 KeybdDriverVKeyToUnicode(UINT32 VirtualKey, KEY_STATE_FLAGS KeyEvent, KEY_STATE KeyState,
void *pKeybdDriverToUnicodeState, UINT32 cBufferSize,
UINT32 *pcCharacters, KEY_STATE_FLAGS *pShiftStateBuffer,
UINT32 *pCharacterBuffer);

Parameters

VirtualKey
Specifies the virtual key causing the event.
KeyEvent
KeyStateDownFlag set or cleared.
KeyState
Specifies the key state.
pKeybdDriverToUnicodeState
Driver-specific TO_UNICODE_STATE.
cBufferSize
Specifies the count of 32-bit entries in each buffer.
pcCharacters
Pointer to a count of characters generated.
pShiftStateBuffer
Pointer to a buffer into which to put the shift state information.
pCharacterBuffer
Pointer to a buffer into which to put the characters.

Remarks

If KeyState is NULL, the driver must fill in the character corresponding to the unshifted state for the virtual key and return.

In all other cases, the KeybdDriverVKeyToUnicode function must update the key state array and fill in the shift state determined from the key state array and, if necessary, update TO_UNICODE_STATE. This means that the count of characters generated is always at least 1. See KEY_STATE_FLAGS in order to generate the shift state without a corresponding character.

Each character should have a corresponding shift state entered into the shift state buffer, even if it is the same as the preceding shift state.

Each entry in the character buffer is 32 bits, whereas a Unicode character is 16 bits. The driver assigns characters to the buffer to clear the high order 16-bits, as in the following code example.

 *pCharacterBuffer = Unicode character; // YES

This function is defined in the Keybdmdd.cpp file.

See Also

KeybdDriverGetInfo, KeybdDriverInitStates


KeybdEventCallback

This function is a prototype of the callback function passed to the KeybdDriverInitialize function.

Syntax

void KeybdEventCallback(UINT32 VirtualKey,
KEY_STATE_FLAGS KeyEvent);

Parameters

VirtualKey
Specifies code for the virtual key or event.
KeyEvent
Specifies the KeyStateDownFlag being set or cleared.

Remarks

The keyboard driver does not implement this function. This is the prototype of this function passed into the driver by the user input system when it calls the KeybdDriverInitialize function. The driver calls the callback function whenever there is a keyboard event.

The KeyStateDownFlag field in the KeyEvent parameter is set for a key-down event and clear for a key-up event. All other bits must be 0. The VirtualKey parameter has more than just the virtual key information. See the Keybddr.h header file for a description of the information in this parameter.

When a keyboard is connected or disconnected, an event must be signaled with the appropriate connect-event code or disconnect-event code set in the VirtualKey parameter.

This function prototype is declared in the Keybddr.h header file.

See Also

KeybdDriverInitialize


KeybdPdd_DllEntry

This function is called by the MDD on DLL state changes.

Syntax

BOOL WINAPI KeybdPdd_DllEntry(HANDLE hinstDLL, DWORD Op, LPVOID lpvReserved);

Parameters

hinstDLL
Specifies a standard instance handle of the DLL.
Op
Specifies a standard DLL entry parameter.
lpvReserved
Specifies a standard DLL entry parameter.

Remarks

This function supports the implementation of the Keyboard Driver PDD.


KeybdPdd_GetEvent

This function is called by the MDD to retrieve keyboard events after the SYSINTR_KEYBD signal is sent.

Syntax

INT WINAPI KeybdPdd_GetEvent(UINT32 VirtualKeys[16], KEY_STATE_FLAGS KeyEvents[16]);

Parameters

VirtualKeys[16]
Specifies the buffer in which to put detected virtual keys.
KeyEvents[16]
Specifies the buffer in which to put key state flags.

Return Values

Number of key events; a value of 0 is allowed.

Remarks

This function supports the implementation of the Keyboard Driver PDD.


KeybdPdd_InitializeDriver

This function is called by the keyboard driver MDD to initialize the keyboard hardware.

Syntax

BOOL WINAPI KeybdPdd_InitializeDriver(PFN_KEYBD_EVENT_CALLBACK pfnKeybdEventCallback);

Parameters

pfnKeybdEventCallback
Pointer to a function used as a callback into the input system.

Remarks

This function supports the implementation of the keyboard driver PDD.


KeybdPdd_PowerHandler

This function is called by the MDD on system power state changes.

Syntax

void WINAPI KeybdPdd_PowerHandler(BOOL bOff);

Parameters

bOff
Boolean. TRUE indicates that the system is being turned off. FALSE indicates that the system is being turned on.

Remarks

This function runs in kernel context and assumes that interrupts are disabled because it works directly with CPU registers. It does not make any system calls or cause tasks to be rescheduled in any way. This function is restricted to reading and writing to preallocated memory. Any subroutines called from this function must follow this restriction.

This function supports the implementation of the Keyboard Driver PDD.


LoadGenericInterfaceDriver

This function is called by USB drivers to load drivers for other interfaces on a device.

Syntax

BOOL LoadGenericInterfaceDriver(USB_HANDLE hDevice, LPCUSB_INTERFACE lpInterface);

Parameters

hDevice
[IN] Handle to a USB device, which is passed in the USBDeviceAttach function.
lpInterface
[IN] Pointer to a USB_INTERFACE structure for an interface.

Return Values

TRUE indicates that a driver was successfully loaded for an interface. FALSE indicates failure.

Remarks

If a client accepts control of a device, this function must be called to load a driver for any uncontrolled interfaces.

This function is defined in the Mousedrv.cpp file.


NDIS_BUFFER_LINKAGE

This macro returns a pointer to a linked buffer as long as it has a pointer to a buffer descriptor.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

PVOID NDIS_BUFFER_LINKAGE(IN PNDIS_BUFFER Buffer);

Parameters

Buffer
Pointer to a buffer descriptor, which must not be chained to a packet descriptor.

Return Values

A pointer to the structure member containing the linkage indicates success. NULL indicates failure.

Remarks

This macro allows a driver to queue allocated buffer descriptors without having to supply its own buffer descriptor linkage.

A driver that uses this macro can be funning at any IRQL.

See Also

NdisAllocateBuffer


NDIS_BUFFER_TO_SPAN_PAGES

This macro determines how many physical pages of memory are being used to back a specified buffer.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

ULONG NDIS_BUFFER_TO_SPAN_PAGES(IN PNDIS_BUFFER Buffer);

Parameters

Buffer
Specifies the buffer descriptor mapping the buffer.

Return Values

The Windows CE version of this macro always returns 1.

Remarks

This macro is used by DMA drivers to determine how many physical discontiguities exist in a specified virtual buffer.

A driver that uses this macro can be running at any IRQL.


NDIS_PHYSICAL_ADDRESS_CONST

This macro initializes a static constant of type physical address.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NDIS_PHYSICAL_ADDRESS_CONST(IN ULONG Low,
IN LONG High);

Parameters

Low
Specifies the low-order bytes of the physical address.
High
Specifies the high-order bytes of the physical address.

Remarks

A driver that uses this macro can be running at any IRQL.


NDIS_SET_PACKET_HEADER_SIZE

This macro sets the HeaderSize member in the NDIS_OOB_DATA structure associated with a specified packet descriptor for a subsequent receive indication.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

NDIS_SET_PACKET_HEADER_SIZE(IN PNDIS_PACKET Packet,
IN UINT HdrSize);

Parameters

Packet
Pointer to a driver-allocated packet descriptor.
HdrSize
Specifies the medium-specific number of bytes in the net packet header.

Remarks

The HeaderSize member in NDIS_PACKET_OOB_DATA associated with a packet descriptor specifies the number of bytes of medium-specific header in the buffer mapped by the initial buffer descriptor chained to the packet descriptor.

A lower-level driver sets this member with this macro in the out-of-band data blocks for the receive packets it subsequently indicates with the NdisMIndicateReceivePacket function. Typically, a miniport sets the HeaderSize once for each packet descriptor that it allocates with the NdisAllocatePacket function for subsequent receive indications, depending on the medium that it selects during initializaiton. If such a driver clears the out-of-band data block with the NDIS_OOB_DATA_FROM_PACKET macro and the NdisZeroMemory function when it regains ownership of its receive packet descriptors. That driver must call this macro before it reuses each packet descriptor in a subsequent indication.

When such an indication is made, bound protocols can retrieve this information with the NDIS_GET_PACKET_HEADER_SIZE macro.

A driver that calls this macro runs at IRQL<=DISPATCH_LEVEL.

See Also

NdisAllocatePacket, NdisMIndicateReceivePacket, NdisSend, NdisZeroMemory


NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO

This macro sets the MediaSpecificInformation pointer and the SizeMediaSpecificInfo value in the out-of-band data block associated with a specified packet descriptor.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(
IN PNDIS_PACKET Packet, IN PVOID MediaSpecificInfo,
IN UINT SizeMediaSpecificInfo);

Parameters

Packet
Pointer to a driver-allocated packet descriptor.
MediaSpecificInfo
Pointer to a caller-supplied buffer containing medium-specific information, such as packet priority, to be set in the MediaSpecificInformation member of the NDIS_PACKET_OOB_DATA structure associated with the specified packet descriptor. This parameter cannot be NULL.
SizeMediaSpecificInfo
Specifies the number of bytes of information supplied by the MediaSpecificInformation member. This parameter cannot be 0.

Remarks

Depending on the medium, an underlying driver might set these members with this macro in the out-of-band data blocks associated with the packet descriptors that it allocates for receive indications. When a bound protocol is called with the indication, it uses the NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO macro or, possibly, the NdisQueryReceiveIndication function, to access the supplied information.

Depending on the medium of the underlying driver to which it is bound, a protocol might set MediaSpecificInformation and SizeMediaSpecificInfo in the out-of-band blocks associated with the packet descriptors that it allocates for sends. The underlying driver uses NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO to access the supplied information.

In either case, while a higher-level protocol is consuming a receive indication or a lower-level miniport is processing a send, that driver must have exclusive access to the buffer at MediaSpecificInformation. This restriction implies the following:

  • A miniport cannot access the buffer that it sets up with out-of-band information when the NdisMIndicateReceivePacket function returns control if NDIS_STATUS_PENDING is set in the Status member of the associated structure. The driver uses NDIS_GET_PACKET_STATUS to determine whether each packet in the packet array that it just indicated has this status set or has been returned with NDIS_STATUS_SUCCESS.
  • A protocol driver cannot access the buffer that it set up with out-of-band information for a send, or anything else in the structure associated with a packet descriptor that it passes to the NdisSend function, until the packet descriptor is returned to its ProtocolSendComplete function.

    Because NDIS queues send packets and resubmits them if the MiniportSend function returns NDIS_STATUS_RESOURCES for the Status of a packet in a submitted array, the final status of each packet in a send (array) is volatile until that packet has been returned to ProtocolSendComplete.

A protocol driver can call the NdisQueryReceiveInformation function to obtain a copy of the NDIS_PACKET_OOB_DATA structure associated with a packet descriptor when its ProtocolReceive function is given an indication. However, this call is superfluous if the protocol is bound to an underlying driver that does not supply out-of-band information with its indications.

A driver that uses this macro runs at IRQL <=DISPATCH_LEVEL.

See Also

NdisAllocatePacket, NdisSend, NDIS_SET_PACKET_STATUS


NDIS_SET_PACKET_STATUS

This macro sets the Status member in the structure associated with a specified packet descriptor just before a driver calls the NdisMIndicateReceivePacket function or before a driver’s MiniportSendPackets function returns control.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

NDIS_SET_PACKET_STATUS(IN PNDIS_PACKET Packet,
IN NDIS_STATUS Status);

Parameters

Packet
Pointer to a packet descriptor allocated either by the caller, for a receive indication, or by a protocol, for a send.
Status
Specifies the status to be set; either of the following:
NDIS_STATUS_SUCCESS
The driver is relinquishing ownership of the packet to be indicated by the NdisIndicateReceivePacket function until the packet descriptor is returned to its MiniportReturnPacket function.

Protocols that receive the indication can use the packet descriptor, along with all buffers mapped by buffer descriptors chained to the packet descriptor and any out-of-band information supplied with the packet, to copy the indicated net packet data, possibly forwarding the processed copy to interested clients.

NDIS_STATUS_RESOURCES
The driver is retaining ownership of the packet to be indicated by the NdisMIndicateReceivePacket function and of all subsequent packets in the packet array. All these packets are indicated, one at a time, to the ProtocolReceive functions of bound protocols.

Setting this status forces bound protocols to return ownership of each such packet descriptor, of any medium-specific buffer in the out-of-band data block for each packet descriptor, and of the memory mapped by each packet descriptor’s respective chained buffer descriptors to the indicating driver more quickly. The protocols must wait for a call to their ProtocolReceiveComplete functions to begin postprocessing the data that they copied from the indication and forwarding the processed data to their clients.

An indicating driver sets this status if it is running low on packet pool or buffer pool. An indicating NIC driver usually sets this status if it is running low on NIC receive buffers due to high network traffic. A busmaster DMA NIC driver might call the NdisMAllocateSharedMemoryAsync function in these circumstances to get additional NIC receive buffer space.

NDIS assumes that, if this status is set for a packet in an indicated array, it is set for all subsequent packets in that array. Consequently, an indicating driver need not set the status for subsequent packet descriptors in an array after it sets this status in the out-of-band block for one packet descriptor.

For packet descriptors used in sends, the MiniportSendPackets function can set one of the following values:

NDIS_STATUS_PENDING
The driver completes the requested send operation asynchronously.

After MiniportSendPackets returns control, the driver calls the NdisMSendComplete function with a final completion status for the specified packet descriptor, which NDIS propagates to the ProtocolSendComplete function of the driver that allocated the resources specified by the packet descriptor and initiated the send.

NDIS_STATUS_RESOURCES
The driver cannot process all sends specified in a packet array due to current resource constraints.

NDIS assumes that the Status member for all subsequent packet descriptors in the array sent to MiniportSendPackets is set to the same value. NDIS queues these packet descriptors internally in the same order for resubmission to MiniportSendComplete, whichever call occurs first. NDIS reflects this miniport-set status value to protocols as NDIS_STATUS_PENDING.

NDIS_STATUS_XXX
MiniportSendPackets is completing a specified send request before it returns control.

Whether such a send packet is completed with NDIS_STATUS_SUCCESS or a driver-determined error status, MiniportSendPackets must set the Status member for the specified packet descriptor so that NDIS can reflect this status back to the protocol that initiated the send when NDIS calls ProtocolSendComplete with the returned packet descriptor.

Remarks

Only drivers that indicate receives with NdisMIndicateReceivePacket to bound protocols and/or drivers that have MiniportSendPackets functions use this macro.

After such an underlying driver has set the Status for a number of packet descriptors in an array and called NdisMIndicateReceivePacket with the array of pointers to those packet descriptors, it uses the NDIS_GET_PACKET_STATUS macro when NdisMIndicateReceivePacket returns control. The returned Status in the NDIS_PACKET_OOB_DATA structure associated with each packet descriptor that the driver indicates with NDIS_STATUS_SUCCESS determines what the indicating driver does next, as follows:

NDIS_STATUS_SUCCESS
If this is set on return from a miniport’s call to NdisMIndicatePacket, the miniport regains ownership of the following:
  • The packet descriptor
  • The associated out-of-band data block associated with the packet descriptor and of any media-specific information buffer specified in this block
  • All buffers mapped by buffer descriptors chained to the packet descriptor

The driver can prepare these descriptors, the out-of-band block, and media-specific information buffer, if any, for reuse in subsequent receive indications immediately.

NDIS_STATUS_PENDING
If this is set on return from NdisMIndicateReceivePacket, protocols retain ownership of the packet descriptor, of its associated out-of-band data block, of any buffer specified in this block, and of all buffers mapped by buffer descriptors chained to the packet descriptor until the packet descriptor is returned to the indicating driver’s MiniportReturnPacket function. However, protocols are given read-only access to these minport-allocated resources.

When MiniportSendPackets sets the Status for an incoming send packet to anything other than NDIS_STATUS_PENDING or NDIS_STATUS_RESOURCES, it completes the packet and relinquishes ownership of all resources specified by the associated packet descriptor. NDIS returns the packet descriptor to the ProtocolSendComplete function of the allocating driver and propagates the miniport-set status value as an input parameter to ProtocolSendComplete. Otherwise, the underlying driver calls NdisMSendComplete with the packet descriptor and final status when the asynchronous send operation is done.

Protocol drivers should never test the Status value in the associated out-of-band data block on return from NdisSend. NDIS or the underlying driver retains ownership of the packet descriptor, of the associated out-of-band block, any buffers specified in this block, and of all buffers mapped by buffer descriptors chained to the packet descriptor until the ProtocolSendComplete function is called with the packet descriptor.

A driver that uses this macro runs at IRQL <=DISPATCH_LEVEL.

See Also

NdisAllocatePacket, NdisMIndicateReceivePacket, NdisMSendComplete, NdisSend, NDIS_SET_PACKET_HEADER_SIZE, NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO, NDIS_SET_PACKET_TIME_RECEIVED, NDIS_SET_PACKET_TIME_SENT


NDIS_SET_PACKET_TIME_RECEIVED

This macro sets the TimeReceived value in the out-of-band data block associated with a specified packet descriptor.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

NDIS_SET_PACKET_TIME_RECEIVED(IN PNDIS_PACKET Packet,
IN ULONGLONG TimeReceived);

Packet
Pointer to a packet desciptor allocated by the caller for receive indications.
TimeReceived
Specifies the system time at which the packet was received from the remote node on the network.

Remarks

Drivers use this macro to set this time stamp in the out-of-band data block associated with a packet descriptor before calling the NdisMIndicateReceivePacket function. Miniports that indicate multipacket receives can set the TimeReceived parameter for each packet in an idicated array to the same value before making an indication, particularly if the NIC has no internal clock, so the NIC driver calls the NdisGetCurrentSystemTime function.

All time stamps set in the NDIS_PACKET_OOB_DATA structures associated with packet descriptors are expressed in system time units as the number of 100-nanosecond intervals since January 1, 1601. A driver calls NdisGetCurrentSystemTime to supply the TimeReceived parameter to NDIS_SET_PACKET_TIME_RECEIVED.

If the ProtocolReceive function is called with an indicated packet descriptor for which the underlying driver set the TimeReceived time stamp, ProtocolReceive calls NdisQueryReceiveInformation to get this time stamp.

A driver that calls this macro runs in IRQL <=DISPATCH_LEVE.

See Also

NdisMIndicateReceivePacket, NDIS_SET_PACKET_TIME_SENT


NDIS_SET_PACKET_TIME_SENT

This macro sets the TimeSent value in the out-of-band data block associated with a specified packet descriptor.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

NDIS_SET_PACKET_TIME_SENT(IN PNDIS_PACKET Packet,
IN ULONGLONG TimeSent);

Parameters

Packet
Pointer to a packet descriptor allocated by the caller for receive indications.
TimeSent
Specifies the system time at which the packet was transmitted over the network from a remote node.

Remarks

Miniports can use this macro to set this time stamp in the out-of-band data block associated with a packet descriptor that they are about to indicate with the NdisMIndicateReceivePacket function.

All time stamps set in the NDIS_PACKET_OOB_DATA structures associated with packets are expressed in system time units as the number of 100-nanosecond intervals since January 1, 1601.

When a protocol driver’s ProtocolReceivePacket function is called with such an indication, it can use the NDIS_GET_PACKET_TIME_SENT macro to retrieve the TimeSent time stamp, using the Packet pointer that it is given on entry.

If the ProtocolReceive function is called with an indicated packet descriptor for which the underlying driver set the TimeSent time stamp, ProtocolReceive calls the NdisQueryReceiveInformation function to get this time stamp.

A driver that uses this macro runs at IRQL <=DISPATCH_LEVEL.

See Also

NdisMIndicateReceivePacket, NDIS_SET_PACKET_TIME_RECEIVED


NDIS_SET_PACKET_TIME_TO_SEND

This function sets the TimeToSend value in the out-of-band data block associated with a specified packet descriptor.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

NDIS_SET_PACKET_TIME_TO_SEND(IN PNDIS_PACKET Packet,
IN ULONGLONG TimeToSend);

Parameters

Packet
Pointer to a packet descriptor allocated by the caller for a send.
TimeToSend
Specifies the system time at which the packet should be transmitted over the network.

Remarks

Protocols can use this macro to set this time stamp in the out-of-band data block associated with a driver-allocated packet descriptor to be passed in a subsequent call to the NdisSend function.

All time stamps set in the NDIS_PACKET_OOB_DATA blocks associated with packet descriptors are expressed in system time units as the number of 100-nanosecond intervals since January 1, 160l.

A protocol can call the NdisGetCurrentSystemTime function and add some number of system time units to the returned value in order to supply the TimeToSend argument to this macro, unless the client that initiated the send request has already supplied such a time stamp.

A driver that uses this macro runs at IRQL <= DISPATCH_LEVEL.

See Also

NdisSend


NdisAcquireSpinLock

This function acquires a spin lock so that the caller gains exclusive access to the resources, shared among driver functions, that the spin lock protects.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisAcquireSpinLock(IN PNDIS_SPIN_LOCK SpinLock);

Parameters

SpinLock
Pointer to an opaque spin lock, already initialized by the caller.

Remarks

In Windows CE, NDIS spin locks are implemented using critical sections.

The driver must initialize a variable of type NDIS_SPIN_LOCK with the NdisAllocateSpinLock function before it calls any other NDIS SpinLock function. The driver must provide resident storage for the spin lock(s) it uses.

After acquiring a spin lock with this function, the caller releases that lock with a call to the NdisReleaseSpinLock function. A driver must call NdisReleaseSpinLock following each call to this function. Otherwise, a deadlock occurs, hanging the driver.

A spin lock acquired with the NdisDprAcquireSpinLock function must be released with the NdisDprReleaseSpinLock function.

A driver should never hold a spin lock for an extended period—more than a few instructions. Holding a spin lock for longer than 25 microseconds degrades both system and driver performance.

A miniport driver cannot use a spin lock to protect resources that its other functions share with the MiniportISR and/or the MiniportDisableInterrupt functions. Instead, a miniport must call the NdisMSynchronizeWithInterrupt function so that its MiniportSynchronizeISR function accesses such shared resources at the same DIRQL at which its MiniportISR and/or MiniportDisableInterrupt functions do.

A driver that calls this function runs at IRQL <=DISPATCH_LEVEL.

See Also

NdisDprAcquireSpinLock, NdisMSynchronizeWithInterrupt, NdisReleaseSpinLock


NdisAdjustBufferLength

This function modifies the length specified in a buffer descriptor allocated or copied by the caller.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisAdjustBufferLength(IN PNDIS_BUFFER Buffer,
IN UINT Length);

Parameters

Buffer
Pointer to the buffer descriptor previously allocated with the NdisAllocateBuffer function.
Length
Specifies the new length, in bytes, to be set in the buffer descriptor.

Remarks

The caller of this function can pass only a buffer descriptor that was allocated by the caller. It cannot pass a buffer descriptor that was allocated by another driver.

For example, the driver of a busmaster DMA NIC calls this function with buffer descriptors that it allocated to specify receive buffers in its shared memory block. Before such a driver indicates received data, it calls this function to make the buffer descriptor that it includes in the receive indication match the size of the received data if it is less than the size of the NIC’s receive buffer. When a receive packet with such an adjusted buffer descriptor has been consumed and returned to the miniport, the driver again calls this function to make the buffer descriptor match the actual size of its receive buffer again.

The Length parameter passed to this function cannot be larger than the Length that was passed to the NdisAllocateBuffer function when the buffer descriptor was allocated.

The caller of this function must restore the length to its original value before it frees the buffer descriptor with the NdisFreeBuffer function.

The driver must release any spin lock that it is currently holding before calling this function.

A driver calling this function can run at any IRQL, but usually runs at IRQL <=DISPATCH_LEVEL.

See Also

NdisAllocateBuffer, NdisFreeBuffer, NdisReleaseSpinLock


NdisAllocateBuffer

This function creates a buffer descriptor mapping a specified virtual (sub)range within an already allocated, nonpaged memory block.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisAllocateBuffer(OUT PNDIS_STATUS Status,
OUT PNDIS_BUFFER *Buffer, IN NDIS_HANDLE PoolHandle,
IN PVOID VirtualAddress, IN UINT Length);

Parameters

Status
Pointer to a caller-supplied variable in which this function returns the final status of the buffer allocation.
Buffer
Pointer to a caller-supplied variable in which this function returns a pointer to the allocated buffer descriptor.
PoolHandle
Handle returned by a preceding call to the NdisAllocateBufferPool function.
VirtualAddress
Pointer to the base virtual address of previously allocated system-space memory to be mapped in the returned buffer descriptor.
Length
Specifies the number of bytes to be mapped.

Return Values

NDIS_STATUS_SUCCESS indicates success. NDIS_STATUS_FAILURE indicates failure.

Remarks

This function allocates storage for and initializes a buffer descriptor to map a specified range of previously allocated memory, such as memory used for a packet header or an NIC receive buffer.

Buffer descriptor allocation draws on the buffer pool that NdisAllocateBufferPool creates. A driver can call this function as many times as necessary to allocate the buffer descriptors that it requires if it called NdisAllocateBufferPool during initialization.

The driver must release any spin lock that it is currently holding before calling this function.

All lower-level NDIS drivers must allocate all buffer descriptors that they chain to packets from a buffer pool. Only highest-level protocol drivers can be given OS-dependent descriptors mapping virtual memory ranges, and, if these memory descriptors are equivalent to NDIS buffer descriptors, a highest-level protocol can pass such descriptors as parameters to NDIS functions.

A driver that calls this function runs at IRQL <=DISPATCH_LEVEL.

See Also

NdisAllocateBufferPool, NdisAllocateMemory, NdisFreeBuffer


NdisAllocateBufferPool

This function returns a handle with which the caller can allocate buffer descriptors by calling the NdisAllocateBuffer function.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisAllocateBufferPool(OUT PNDIS_STATUS Status,
OUT PNDIS_HANDLE PoolHandle, IN UINT NumberOfDescriptors);

Parameters

Status
Pointer to a caller-supplied variable in which this function returns the final status of the buffer pool allocation.
PoolHandle
Pointer to a caller-supplied variable in which this function returns a handle to the buffer pool. This handle is a required parameter to the NDIS buffer functions that the driver calls subsequently.
NumberOfDescriptors
Specifies the number of buffer descriptors that the caller expects to allocate from the buffer pool without releasing any allocated buffer descriptors back to the pool.

Return Values

Always returns NDIS_STATUS_SUCCESS.

Remarks

After this function returns, the driver calls the NdisAllocateBuffer function one or more times to allocate the buffer descriptors that it requires. A driver should call this function during initialization.

The NumberOfDescriptors parameter specified by an NIC driver usually depends on the features of the NIC. For example, the driver of a busmaster DMA NIC with ring buffers would specify at least a large enough NumberOfDescriptors to map the full ring.

The NumberOfDescriptors specified in the call to this function is the effective limit on how many times the driver can call NdisAllocateBuffer before it must call the NdisFreeBuffer function to return a buffer descriptor to the free list for the buffer pool.

When a driver no longer needs the buffer pool that it allocated, it calls the NdisFreeBufferPool function to release the buffer pool handle.

The driver must release any spin lock that it is holding before calling this function.

All lower-level NDIS drivers must allocate all buffer descriptors that they chain to packets from a buffer pool. Only highest-level protocol drivers can be given OS-dependent descriptors mapping virtual memory ranges. If these memory descriptors are equivalent to NDIS buffer descriptors, a highest-level protocol can pass such descriptors as parameters to NDIS functions.

A driver that calls this function runs at IRQL <=DISPATCH_LEVEL.

See Also

NdisAdjustBufferLength, NdisAllocateBuffer, NdisChainBufferAtBack, NdisChainBufferAtFront, NdisFreeBuffer, NdisFreeBufferPool, NdisQueryBuffer, NdisReleaseSpinLock


NdisAllocateMemory

This function allocates resident (nonpaged) system-space memory. The memory can be allocated within a specified address limit and, if necessary, can be uncached as well.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

NDIS_STATUS NdisAllocateMemory(OUT PVOID *VirtualAddress,
IN UINT Length, IN UINT MemoryFlags,
IN NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress);

Parameters

VirtualAddress
Pointer to a caller-supplied variable in which this function returns the base virtual address of the allocated memory or NULL if memory of the specified type is unavailable.
Length
Specifies the size, in bytes, to be allocated.
MemoryFlags
Specifies 0 or a bitmask designating the type(s) of memory to allocate. One of the following values:
0
Allocate nonpaged system-space memory.
NDIS_MEMORY_CONTIGUOUS
Not supported.
NDIS_MEMORY_NONCACHED
Allocate noncached memory.
HighestAcceptableAddress
Specifies –1.

Return Values

NDIS_STATUS_SUCCESS indicates that the caller can use the allocated memory range starting at the value returned at the VirtualAddress parameter. NDIS_STATUS_FAILURE indicates that the attempt to allocate the requested memory failed. This does not necessarily mean that a subsequent call will fail.

Remarks

If the NDIS_MEMORY_NONCACHED flag is specified, Windows CE NDIS uses the VirtualAlloc function to allocate the memory; otherwise, it uses the LocalAlloc function.

Any NDIS driver might call this function with the MemoryFlags set to 0. for example, NDIS drivers that export a set of NDIS upper-edge (miniport) functions can call this function to allocate a context area in which the driver maintains per-NIC or per-virtual-NIC run-time state information and pass the pointer returned at VirtualAddress to the NdisMSetAttributes or the NdisMSetAttributesEx function. NDIS drivers that export a set of NDIS lower-edge (protocol) functions can also call this function whenever such a driver needs to allocate buffer space.

Only NIC miniports set the MemoryFlags with either or both of the flags when they make initialization-time calls to this function. During initialization, miniport drivers allocate these types of memory to be shared with their NICs.

If such a miniport specifies physically contiguous memory in a call to this function, the virtual memory allocation maps to a single physically contiguous region. If a miniport specifies noncached memory, the allocated virtual range is not cached. An NIC driver can access noncached memory without flushing cache buffers during DMA operations.

Whatever the value of the input MemoryFlags, a successful caller to this function uses a range of virtual addresses to access the allocated memory. Depending on the size of the allocation and on the type of memory requested, one or more physical memory ranges (pages) back this single virtual range.

An NIC driver should never request more noncached memory than it needs.

If an initialization-time call fails, an NIC driver can attempt to allocate one or more smaller blocks of noncached memory, rather than failing to initialize if it cannot allocate a large block.

A driver that calls this function can run at IRQL <=DISPATCH_LEVEL to allocate memory from a nonpaged pool. NIC drivers that allocate noncached memory must be running at IRQL PASSIVE_LEVEL during initialization.

See Also

NdisFreeMemory, NdisMSetAttributes, NdisMSetAttributesEx


NdisAllocatePacket

This function allocates and initializes a packet descriptor.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisAllocatePacket(OUT PNDIS_STATUS Status,
OUT PNDIS_PACKET *Packet, IN NDIS_HANDLE PoolHandle);

Parameters

Status
Pointer to a caller-supplied variable in which this function returns the final status of the request; one of the following:
NDIS_STATUS_SUCCESS
The caller can use the packet descriptor returned by the Packet parameter.
NDIS_STATUS_RESOURCES
The free list for the packet pool currently has no available entries. A subsequent call to the NdisFreePacket function returns the specified entry to the free list.
Packet
Pointer to a caller-supplied variable in which this function returns a pointer to the allocated packet descriptor.
PoolHandle
Handle returned by a preceding call to the NdisAllocatePacketPool function.

Remarks

NDIS drivers must allocate packet descriptors from a packet pool. Protocol drivers call this function one or more times for their subsequent calls to the NdisSend function. Miniports call this function one or more times for subsequent calls to the NdisMIndicateReceivePacket function. NDIS intermediate drivers must call this function to repackage sends and receive indications in fresh packet descriptors before passing incoming transfer requests on to other NDIS drivers.

Each packet descriptor eventually has one or more buffer descriptors chained to it. This function initializes the packet descriptor at 0 and sets its buffer chain pointer to NULL. The caller must chain the buffer descriptor(s) mapping the packet data to the packet descriptor before it is sent or indicated. Most NDIS drivers allocate buffer descriptors with the NdisAllocateBuffer function.

Drivers must use the NDIS_SET_PACKET_XXX macros to access or set up any out-of-band information associated with the packet descriptor.

A driver that calls this function runs at IRQL <=DISPATCH_LEVEL.

See Also

NdisAllocateBuffer, NdisAllocatePacketPool, NdisFreePacket, NdisMEthIndicateReceive, NdisMIndicateReceivePacket, NdisSend, NDIS_SET_PACKET_HEADER_SIZE, NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO, NDIS_SET_PACKET_STATUS, NDIS_SET_PACKET_TIME_RECEIVED, NDIS_SET_PACKET_TIME_SENT, NDIS_SET_PACKET_TIME_TO_SEND


NdisAllocatePacketPool

This function allocates and initializes a block of storage for a pool of packet descriptors.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisAllocatePacketPool(OUT PNDIS_STATUS Status,
OUT PNDIS_HANDLE PoolHandle, IN UINT NumberOfDescriptors,
IN UINT ProtocolReservedLength);

Parameters

Status
Pointer to a caller-supplied variable in which this function returns the status of the packet pool allocation; one of the following:
NDIS_STATUS_SUCCESS
The driver can make calls to the NdisAllocatePacket function when it needs packet descriptors to make indications up to higher-level drivers or to send packets down to lower-level drivers.
NDIS_STATUS_RESOURCES
The attempt to allocate a packet pool failed, possibly due to a shortage of memory. However, the caller might attempt to decrease the NumberOfDescriptors parameter and call again immediately.
PoolHandle
Handle to the packet pool. This handle is a required parameter to the NDIS packet functions that the driver calls subsequently.
NumberOfDescriptors
Specifies the number of packet descriptors that the pool should contain.
ProtocolReservedLength
Specifies the number of bytes to be allocated for the ProtocolReserved array of each packet descriptor. For packet descriptors to be used in receive indications, this parameter can be at most 16 bytes.

Return Values

A handle to the packet pool indicates success.

Remarks

The caller should save the handle returned by this function. Usually, the driver next calls the NdisAllocatePacket function one or more times with this handle to allocate a set of packet descriptors. The NumberofDescriptors specified in the call to this function is the effective limit on how many times the driver can call NdisAllocatePacket before it must call the NdisFreePacket function to return a packet descriptor to the free list for the packet pool.

Since packets sent or indicated are returned to the allocating driver, it can reuse each packet descriptor after calling the NdisReinitializePacket function and setting it up again with a chain of buffer descriptors, or the driver can call the NdisFreePacket function to return that packet to the free list. Reinitializing and reusing packets allocated from the packet pool is far faster than freeing and reallocating them. Before a driver calls NdisReinitializePacket with a packet descriptor, it must save the pointers to buffer descriptors that are chained to the packet descriptor since NdisReinitializePacket sets the head of the buffer chain to NULL.

When the driver no longer needs the packet pool, it calls the NdisFreePacketPool function to release the packet pool storage.

The driver must release any spin lock that it is holding before calling this function.

A driver that calls this function runs at IRQL <=DISPATCH_LEVEL.

See Also

NdisAllocatePacket, NdisFreePacketPool, NdisMIndicateReceivePacket, NdisReinitializePacket, NdisUnchainBufferAtBack, NdisUnchainBufferAtFront


NdisAllocateSpinLock

This function initializes a variable of type NDIS_SPIN_LOCK, used to synchronize access to resources shared among driver functions not related to interrupts.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID
NdisAllocateSpinLock (IN PNDIS_SPIN_LOCK SpinLock);

Parameters

SpinLock
Pointer to an opaque variable that represents a spin lock.

Remarks

Before a driver calls NdisAcquireSpinLock, NdisDprAcquireSpinLock, or any of the NdisInterlocked XXX functions, it must call this function to initialize the spin lock passed as a required parameter to these Ndis XXX functions. The caller must provide nonpaged storage for the variable at SpinLock.

After calling this function, the driver can call NdisAcquireSpinLock to obtain exclusive use of the resource(s) that the spin lock protects. When resource access is complete, the driver calls NdisReleaseSpinLock so that other driver functions can access the resource(s) protected by that spin lock.

As a general rule, a driver should not pass the same spin lock to every Ndis XXX SpinLock and NdisInterlocked XXX that it calls subsequently. In this way, any driver might initialize more than one spin lock with this function.

Each spin lock that a driver allocates protects a discrete set of shared resources from simultanous access by driver functions that run at IRQL <= DISPATCH_LEVEL. For example, a driver that maintains an internal queue of packets might initialize one spin lock to protect its queue and another to protect a set of state variables that several driver functions, not including the MiniportISR or MiniportDisableInterrupt function, access while the driver is processing packets.

A driver should never use two spin locks to protect the same resources because nested spin-lock acquisitions frequently cause deadlocks. Even if a driver could be designed to prevent deadlocks, nested spin-lock acquisitions have an adverse effect on driver performance and I/O throughput.

A miniport driver cannot use a spin lock to protect resources that its non-ISR functions share with its MiniportISR or the MiniportDisableInterrupt function. To access resources shared with a MiniportISR or MiniportDisableInterrupt function, a miniport must call NdisMSynchronizeWithInterrupt to have its MiniportSynchronizeISR function access those resources at DIRQL.

When a driver no longer requires resource protection, for example, when an NIC is being removed and the driver is releasing the resources that it allocated for that NIC, the driver calls NdisFreeSpinLock.

Freeing a spin lock and releasing a spin lock must be distinguished. NdisFreeSpinLock clears the memory at SpinLock so it no longer represents a spin lock. Releasing an acquired spin lock with NdisReleaseSpinLock allows another thread of execution to acquire that spin lock.

A driver that calls this function can run at any IRQL. Usually a caller is running at IRQL PASSIVE_LEVEL during initialization.

See Also

NdisAcquireSpinLock, NdisDprAcquireSpinLock, NdisDprReleaseSpinLock, NdisFreeSpinLock, NdisMSynchronizeWithInterrupt, NdisReleaseSpinLock


NdisAnsiStringToUnicodeString

This function converts a specified counted ASCII string into a counted Unicode string. The translation conforms to the current system locale information.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

NDIS_STATUS NdisAnsiStringToUnicodeString(
IN OUT PNDIS_STRING DestinationString,
IN PNDIS_ANSI_STRING SourceString);

Parameters

DestinationString
Pointer to a caller-allocated buffer in which this function returns the converted Unicode string.
SourceString
Pointer to the ASCII string to be converted.

Return Values

NDIS_STATUS_SUCCESS indicates success. Otherwise, the contents of the buffer at DestinationString are unaffected.

Remarks

The caller must allocate storage for both the source and destination strings and release these buffers as soon as the strings are no longer needed. The buffer at DestinationString must be at least twice the size of that at SourceString.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisFreeString, NdisInitAnsiString, NdisInitializeString, NdisInitUnicodeString, NdisUnicodeStringToAnsiString


NdisChainBufferAtBack

This function links a specified buffer descriptor to the tail of the buffer-descriptor chain attached to a packet descriptor.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisChainBufferAtBack(IN OUT PNDIS_PACKET Packet,
IN OUT PNDIS_BUFFER Buffer);

Parameters

Packet
Pointer to the packet descriptor.
Buffer
Pointer to the caller-supplied buffer descriptor to be added to the chain.

Remarks

This function links the specified buffer descriptor either to the end of an existing chain or, if the specified packet has no associated buffer descriptors already, to the head of the chain.

It also resets the valid counts for the packet to FALSE, thus forcing the NdisQueryPacket function to recalculate information about the specified packet if it is called subsequently with that packet.

A driver that calls this function can run at any IRQL, but usually runs at IRQL <=DISPATCH_LEVEL.

See Also

NdisChainBufferAtFront, NdisQueryPacket, NdisUnchainBufferAtBack


NdisChainBufferAtFront

This function links a specified buffer descriptor to the head of the buffer-descriptor chain attached to a packet descriptor.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisChainBufferAtFront(IN OUT PNDIS_PACKET Packet,
IN OUT PNDIS_BUFFER Buffer);

Parameters

Packet
Pointer to the packet descriptor.
Buffer
Pointer to the caller-supplied buffer descriptor to be added to the chain.

Remarks

This function links the specified buffer descriptor at the head of the chain for the specified packet. It also resets the valid counts for the packet to FALSE, thus forcing the NdisQueryPacket function to recalculate information about the specified packet if it is called subsequently with that packet.

A driver that calls this function can run at any IRQL, but usually runs at IRQL <=DISPATCH_LEVEL.

See Also

NdisChainBufferAtBack, NdisQueryPacket, NdisUnchainBufferAtFront


NdisCloseAdapter

This function releases the binding established and the resources allocated when the protocol called the NdisOpenAdapter function.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisCloseAdapter(OUT PNDIS_STATUS Status,
IN NDIS_HANDLE NdisBindingHandle);

Parameters

Status
Pointer to a caller-supplied variable in which this function returns the status of the close operation; one of the following:
NDIS_STATUS_SUCCESS
The binding is closed, and all resources pertaining to that binding have been released.
NDIS_STATUS_PENDING
A close-adapter request is being handled asynchronously, and the caller’s ProtocolCloseAdapterComplete function will be called when the close operation is done.
NdisBindingHandle
Handle returned by NdisOpenAdapter that identifies the virtual adapter or NIC to be closed.

Remarks

The Windows CE version of NdisDeregisterProtocol frees resources associated with the protocol. It does not close any outstanding bindings or call any adapter-specific ProtocolCloseAdapterComplete or ProtocolStatus functions. Unlike the Windows NT version, it does not unload the miniport driver when there are no more protocol drivers, also known as protocol stacks, bound to it.

As soon as a protocol calls this function, the handle at NdisBindingHandle should be considered invalid by the caller.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisOpenAdapter


NdisCloseConfiguration

This function releases the handle to the Parms registry key returned by the NdisOpenConfiguration or the NdisOpenProtocolConfiguration function.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisCloseConfiguration(IN NDIS_HANDLE ConfigurationHandle);

Parameters

ConfigurationHandle
Handle returned by NdisOpenConfiguration or NdisOpenProtocolConfiguration.

Remarks

This function frees any temporary storage allocated in calls to the other NDIS functions that require the returned ConfigurationHandle as a parameter.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisOpenConfiguration, NdisOpenProtocolConfiguration, NdisReadConfiguration, NdisReadNetworkAddress, NdisWriteConfiguration


NdisCopyFromPacketToPacket

This function copies a specified range of data from one packet to another.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisCopyFromPacketToPacket(IN PNDIS_PACKET Destination,
IN UINT DestinationOffset, IN UINT BytesToCopy,
IN PNDIS_PACKET Source, IN UINT SourceOffset,
OUT PUINT BytesCopied);

Parameters

Destination
Pointer to the destination packet descriptor.
DestinationOffset
Specifies the byte offset within the destination packet at which to begin writing the copied data.
BytesToCopy
Specifies the number of bytes to copy.
Source
Pointer to the source packet descriptor.
SourceOffset
Specifies the byte offset within the source packet at which to begin copying the data.
BytesCopied
Pointer to the caller-supplied variable in which this function returns the number of bytes actually copied. This number can be less than the value of BytesToCopy if the source packet runs out of data or the destination packet runs out of space.

Remarks

The caller of this function allocates the destination packet, if not the source packet as well. The packet descriptor of the destination packet should have enough chained buffer descriptors to receive the data.

If the source packet runs out of data or the destination packet out of space before the specified number of bytes has been copied, the copy operation stops. In either case, this function returns the number of bytes successfully copied from the source to the destination packet.

This function does not copy any out-of-band information associated with the specified Source to the Destination. To copy this information, the driver can use pointers returned by NDIS_OOB_DATA_FROM_PACKET, and then call the NdisMoveMemory function.

The driver must release any spin lock that it is holding before calling this function.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

See Also

NdisAllocateBuffer, NdisAllocatePacket, NdisMoveMemory


NdisDeregisterProtocol

This function releases the resources allocated when the driver calls the NdisRegisterProtocol function.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisDeregisterProtocol(OUT PNDIS_STATUS Status,
IN NDIS_HANDLE NdisProtocolHandle);

Parameters

Status
Pointer to a caller-supplied variable that is set to NDIS_STATUS_SUCCESS on return from this function.
NdisProtocolHandle
Specifies the handle returned by NdisRegisterProtocol when the driver initialized.

Remarks

Currently, this function is a stub that does no work. Future versions of Windows CE may implement this function.


NdisDprAcquireSpinLock

This function acquires a spin lock so that the caller can synchronize access to resources shared among driver functions not related to interrupts in a multiprocessor-safe way.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisDprAcquireSpinLock(IN PNDIS_SPIN_LOCK SpinLock);

Parameters

SpinLock
Pointer to an opaque spin lock, already initialized by the caller.

Remarks

In Windows CE, NDIS spinlocks are implemented using critical sections.

The NIC driver must initialize a variable of type NDIS_SPIN_LOCK with the NdisAllocateSpinLock function before it calls any other Ndis XXX SpinLock function. The driver must provide resident storage for the spin lock(s) it uses.

This function is an optimized version of NdisAcquireSpinLock that a miniport can call only while running at IRQL DISPATCH_LEVEL.

After acquiring a spin lock with this function, the caller must release that lock with a call to the NdisDprReleaseSpinLock function. An NIC driver must call NdisDprReleaseSpinLock following each call to this function. Otherwise, a deadlock occurs, hanging the driver.

A spin lock acquired with this function must be released with NdisDprReleaseSpinLock. A spin lock acquired with NdisAcquireSpinLock must be released with NdisReleaseSpinLock.

A driver should never hold a spin lock for an extended period—more than a few instructions. Holding a spin lock for longer than 25 microseconds degrades both system and driver performance.

A miniport driver cannot use a spin lock to protect resources that its other functions share with the MiniportISR and/or MiniportDisableInterrupt functions. Instead, a miniport must call the NdisMSynchronizeWithInterrupt function so that its MiniportSynchronizeISR function accesses such shared resources at the same DIRQL at which its MiniportISR and/or MiniportDisableInterrupt functions do.

A driver that calls this function must be running at IRQL DISPATCH_LEVEL.

See Also

NdisAcquireSpinLock, NdisDprReleaseSpinLock, NdisMSynchronizeWithInterrupt


NdisDprReleaseSpinLock

This function releases a spin lock acquired in the preceding call to the NdisDprAcquireSpinLock function.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisDprReleaseSpinLock(IN PNDIS_SPIN_LOCK SpinLock);

Parameters

SpinLock
Pointer to the acquired spin lock to be released.

Remarks

In Windows CE, NDIS spinlocks are implemented using critical sections.

Release of the spin lock allows another driver function to use the resources that the lock protects after that function acquires the spin lock.

A spin lock acquired with NdisDprAcquireSpinLock must be released with this function. A spin lock acquired with the NdisAcquireSpinLock function must be released with the NdisReleaseSpinLock function.

A driver that calls this function is running at IRQL DISPATCH_LEVEL.

See Also

NdisDprAcquireSpinLock


NdisEqualString

This function compares two strings in the OS-default character set to determine whether the strings are equal.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

BOOLEAN NdisEqualString(IN PNDIS_STRING String1,
IN PNDIS_STRING String2, IN BOOLEAN CaseInsensitive);

Parameters

String1
Pointer to the first string.
String2
Pointer to the second string.
CaseInsensitive
Specifies TRUE if case should be ignored when doing the comparison.

Return Values

Returns TRUE if the two strings are equal.

Remarks

For Windows CE drivers, a string of type NDIS_STRING is a counted, 0-terminated Unicode string.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisInitializeString


NdisFlushBuffer

This function flushes the memory region described by a specified buffer descriptor from all processor caches.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisFlushBuffer(IN PNDIS_BUFFER Buffer,
IN BOOLEAN WriteToDevice);

Parameters

Buffer
Pointer to a buffer description mapping a buffer from which or into which data is transferred as a busmaster DMA operation.
WriteToDevice
Specifies TRUE if the NIC driver calls this function to flush a buffer before making a transfer from host memory to the NIC.

If the NIC driver specifies FALSE, it must ensure that the buffer begins and ends on a cache-line boundary.

Remarks

Drivers of busmaster DMA NICs call this function to maintain data integrity in shared memory. Flushing the buffer ensures coherency between the host memory cache and processor physical memory before a DMA transfer to or from the network interface card.

The driver flushes such a buffer when data that it shares with its NIC might be cached. For any transfer between host memory and a busmaster DMA NIC, the miniport must flush the buffer before the transfer starts. Such a driver also must ensure that host memory is not accessed until the transfer completes.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.


NdisFreeBuffer

This function releases a buffer descriptor obtained in a preceding call to the NdisAllocateBuffer function.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisFreeBuffer(IN PNDIS_BUFFER Buffer);

Parameters

Buffer
Pointer to a buffer descriptor.

Remarks

This function returns the given buffer descriptor to the free list.

A driver must not call the NdisFreePacket function with a packet to which buffers are chained because doing this causes a memory leak. Before it releases such a packet, the driver should either call this function as many times as necessary to release all buffer descriptors chained to the packet or call one of the NdisUnchainBufferAt XXX functions as many times as necessary to save the pointers to all chained buffer descriptors.

The driver must release any spin lock that it is holding before calling this function.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

See Also

NdisAllocateBuffer, NdisFreePacket, NdisReleaseSpinLock, NdisUnchainBufferAtBack, NdisUnchainBufferAtFront


NdisFreeBufferPool

This function releases a handle obtained in a preceding call to the NdisAllocateBufferPool function.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisFreeBufferPool(IN NDIS_HANDLE PoolHandle);

Parameters

PoolHandle
Handle returned when the driver called the NdisAllocateBufferPool function. The pool handle is no longer valid after this function returns.

Remarks

Before calling this function, the driver must call the NdisFreeBuffer function as many times as necessary to release all buffer descriptors that were allocated with the NdisAllocateBuffer function but not yet released. Otherwise, the call to this function causes a memory leak.

The driver must release any spin lock that it is holding before calling this function.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

See Also

NdisAllocateBuffer, NdisAllocateBufferPool, NdisFreeBuffer, NdisReleaseSpinLock


NdisFreeMemory

This function releases a block of memory previously allocated with the NdisAllocateMemory function.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisFreeMemory(IN PVOID VirtualAddress, IN UINT Length,
IN UINT MemoryFlags);

Parameters

VirtualAddress
Pointer to the base virtual address of the allocated memory. This address was returned by the NdisAllocateMemory function.
Length
Specifies the size, in bytes, of the memory block to be released. This parameter must be identical to the Length that was passed to NdisAllocateMemory.
MemoryFlags
Specifies 0 or the bitmask originally passed to NdisAllocateMemory for the preceding range; one of the following:
0
Nonpaged system-space memory.
NDIS_MEMORY_CONTIGUOUS
Physically contiguous memory.
NDIS_MEMORY_NONCACHED
Noncached memory.

This value must be identical to the MemoryFlags parameter that was passed to NdisAllocateMemory.

Remarks

The parameters passed to this function must be identical to those passed to NdisAllocateMemory when the block of memory was allocated. That is, a caller of this function cannot release a subrange of the block that was allocated.

Because noncached memory and contiguous memory are seldom released until the allocating NIC driver is unloading, callers of this function usually are running at IRQL PASSIVE_LEVEL for these types of deallocations.

A driver that calls this function can run at IRQL <= DISPATCH_LEVEL when releasing memory that was allocated from nonpaged system space or that was allocated as noncached memory. Callers must be running at IRQL PASSIVE_LEVEL to release contiguous allocations.

See Also

NdisAllocateMemory


NdisFreePacket

This function releases a packet that was allocated from a packet pool with the NdisAllocatePacket function and returns it to the free list.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisFreePacket(IN PNDIS_PACKET Packet);

Parameters

Packet
Pointer to the packet descriptor returned by the NdisAllocatePacket or the NdisDprAllocatePacket function.

Remarks

Before calling this function, the driver must either call the NdisFreeBuffer function as many times as necessary to release all buffer descriptors chained to the packet or call an NdisUnchainBufferAt XXX function as many times as necessary to save all pointers to buffer descriptors. Otherwise, memory associated with buffer descriptors in the chain remains unusable by the driver and by NDIS until the system is rebooted.

The driver must release any spin lock that it is holding before calling this function.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

See Also

NdisAllocatePacket, NdisFreeBuffer, NdisReleaseSpinLock, NdisUnchainBufferAtBack, NdisUnchainBufferAtFront


NdisFreePacketPool

This function releases a handle to a block of packet pool that was allocated with the NdisAllocatePacketPool function.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisFreePacketPool(IN NDIS_HANDLE PoolHandle);

Parameters

PoolHandle
Handle returned when the driver called NdisAllocatePacketPool. The pool handle is no longer valid after this function returns.

Remarks

This function frees the storage for the packet pool. Before calling this function, the driver must call the NdisFreePacket function as many times as necessary to release all packet descriptors that it has allocated with the NdisAllocatePacket function, but not yet freed.

The driver must also release any spin lock that it is holding before calling this function.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

See Also

NdisAllocatePacket, NdisAllocatePacketPool, NdisFreePacket, NdisReleaseSpinLock


NdisFreeSpinLock

This function releases a spin lock initialized in a preceding call to the NdisAllocateSpinLock function.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOIDNdisFreeSpinLock(IN PNDIS_SPIN_LOCK SpinLock);

Parameters

SpinLock
Pointer to the spin lock to be deinitialized.

Remarks

If the caller of this function needs to use the spin lock again, it must call NdisAllocateSpinLock before passing that spin lock pointer to any of the Ndis XXX SpinLock or NdisInterlocked XXX functions.

A driver that calls this function runs at IRQL PASSIVE_LEVEL. Usually, this function is not called until a driver is unloading.

See Also

NdisAcquireSpinLock, NdisAllocateSpinLock, NdisDprAcquireSpinLock, NdisDprReleaseSpinLock, NdisReleaseSpinLock


NdisFreeString

This function releases storage that was allocated for a buffered string.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisFreeString(IN NDIS_STRING String);

Parameters

String
Pointer to the buffer containing the string.

Remarks

Drivers usually call the NdisInitializeString, NdisIntiAnsiString, and/or NdisInitUnicodeString functions when they are initializing, for example, to set up names passed to the Ndis XXX Configuration functions. For each call it makes to an Ndis XXX String function, the driver should make a corresponding call to this function before its initialization function returns control.

NDIS drivers also can call this function to release buffers that they allocate for calls to the NdisAnsiStringToUnicodeString and NdisUnicodeStringToAnsiString functions.

A driver that calls this function runr at IRQL PASSIVE_LEVEL.

See Also

NdisAnsiStringToUnicodeString, NdisFreeMemory, NdisInitAnsiString, NdisInitializeString, NdisInitUnicodeString, NdisOpenAdapter, NdisRegisterProtocol, NdisUnicodeStringToAnsiString


NdisGetFirstBufferFromPacket

This function returns pointers to the buffer descriptor and base virtual address for the initial buffer chained to a specified packet descriptor, along with the sizes of the initial buffer and total buffer in case the buffer is fragmented.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisGetFirstBufferFromPacket(IN PNDIS_PACKET _Packet,
OUT PNDIS_BUFFER *_FirstBuffer, OUT PVOID *_FirstBufferVA,
OUT PUINT FirstBufferLength, OUT PUINT _TotalBufferLength);

Parameters

Packet
Pointer to the packet descriptor from which this function extracts information about the initial buffer.
FirstBuffer
Pointer to a caller-supplied variable in which this function returns the address of the initial buffer descriptor chained to the given packet descriptor.
FirstBufferVA
Pointer to a caller-supplied variable in which this function returns the base virtual address of the initial buffer associated with the packet.
FirstBufferLength
Pointer to a caller-supplied variable in which this function returns the number of bytes mapped by the initial buffer descriptor chained to the packet descriptor.
TotalBufferLength
Pointer to a caller-supplied variable in which this function returns the total number of bytes mapped by all buffer descriptors chained to the packet descriptor.

Remarks

Drivers use this function to get information about the initial buffer and the amount of data associated with a specified packet faster than they can by making calls the NdisQueryPacket function, and then the NdisQueryBuffer function.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

See Also

NdisGetNextBuffer, NdisQueryBuffer


NdisGetNextBuffer

This function returns the next buffer descriptor in a chain as long as it has a pointer to the current buffer descriptor.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisGetNextBuffer(IN PNDIS_BUFFER CurrentBuffer,
OUT PNDIS_BUFFER *NextBuffer);

Parameters

CurrentBuffer
Pointer to the current buffer descriptor.
NextBuffer
Pointer to a caller-supplied variable in which this function returns a pointer to the buffer descriptor, if any, that follows CurrentBuffer in the buffer descriptor chain.

Remarks

This function returns NULL at NextBuffer if CurrentBuffer points to the last buffer descriptor in the chain.

A driver usually calls this function after it calls the NdisQueryPacket or the NdisGetFirstBufferFromPacket function.

A driver can also call the NdisQueryBuffer function to get details about a buffer descriptor that this function finds.

This function does not perform any synchronization. Therefore, a caller must handle any synchronization issues internally if more than one driver function can access buffer descriptors chained to a packet simultaneously.

A driver that calls this function can run at any IRQL.

See Also

NdisGetFirstBufferFromPacket, NdisQueryBuffer, NdisQueryPacket


NdisGetPacketFlags

This function returns the flags, if any, set by a protocol driver in a specified packet descriptor.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

UINT NdisGetPacketFlags(IN PNDIS_PACKET Packet);

Parameters

Packet
Pointer to the packet.

Return Values

The value of the flags in the specified packet descriptor indicates success. Returns 0 if the packet has no explicitly set flags information.

Remarks

This functionreturns information set in the flags packet descriptor that a protocol driver passes down to the underlying NDIS driver, usually with the NdisSend function. These flags can contain protocol-determined information about the send that is not included in the packet data nor in the out-of-band block associated with the packet descriptor.

Protocol drivers can set the flags in packets to be sent on any medium that transmits data in an expedited manner. The MiniportSendPackets function of an underlying NIC driver calls this function to retrieve this information. For underlying NIC drivers that do not support multipacket sends, calls to this function are unnecessary because the packet flags value is passed as an input parameter to the MiniportSend function.

A driver that calls this function can run at any IRQL.

See Also

NdisSetPacketFlags


NdisGetPhysicalAddressHigh

This function returns the high-order part of a specified physical address.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

ULONG NdisGetPhysicalAddressHigh(
IN NDIS_PHYSICAL_ADDRESS PhysicalAddress);

Parameters

PhysicalAddress
Specifies a physical address of an OS-dependent size.

Return Values

Returns the value of the high-order part of the physical address.

Remarks

A driver that calls this function can be running at any IRQL.

See Also

NdisGetPhysicalAddressLow, NdisSetPhysicalAddressHigh


NdisGetPhysicalAddressLow

This function returns the low-order part of a specified physical address.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

ULONG NdisGetPhysicalAddressLow(
IN NDIS_PHYSICAL_ADDRESS PhysicalAddress);

Parameters

PhysicalAddress
Specifies a physical address of an OS-dependent size.

Return Values

Returns the value of the low-order part of the physical address.

See Also

NdisGetPhysicalAddressHigh, NdisSetPhysicalAddressLow


NdisIMRevertBack

This function returns the function of an intermediate driver to the context in which it was executing before it called the NdisIMSwitchToMiniport function.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisIMRevertBack(IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_HANDLE SwitchHandle);

Parameters

MiniportAdapterHandle
Handle input to the MiniportInitialize function.
SwitchHandle
Handle returned by the immediately preceding call to the NdisIMSwitchToMiniport function.

Remarks

An intermediate driver should call this function as quickly as possible after a driver function makes a successful call to NdisIMSwitchToMiniport.

For example, after a successful call to NdisIMSwitchToMiniport, the Protocol XXX function of an NDIS intermediate driver can safely call NdisM XXX functions commonly called from the MiniportHandleInterrupt or the MiniportTimer functions of underlying NIC drivers. In particular, such a Protocol XXX function can call NdisM XXX functions that indicate up to higher-level protocols bound to the intermediate driver’s virtual NIC.

Until it calls this function, the execution of such a Protocol XXX function prevents other Miniport XXX functions in the same driver from running.

A call to this function without a SwitchHandle returned by a preceding call to NdisIMSwitchToMiniport is a fatal error.

A driver that calls this function is running at IRQL DISPATCH_LEVEL.

See Also

NdisIMSwitchToMiniport, NdisMEthIndicateReceive, NdisMIndicateReceivePacket, NdisMIndicateStatus


NdisIMSwitchToMiniport

This function allows an intermediate driver function to call NdisM XXX functions normally called only from Miniport XXX functions, as, for example, to make indications up to higher-level protocols.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

BOOLEAN NdisIMSwitchToMiniport(
IN NDIS_HANDLE MiniportAdapterHandle,
OUT PNDIS_HANDLE SwitchHandle);

Parameters

MiniportAdapterHandle
Handle input to the MiniportInitialize function.
SwitchHandle
Pointer to a variable in which this function returns a handle if the call succeeds.

Return Values

Returns TRUE if the caller can safely call miniport-only NdisM XXX functions until it makes a reciprocal call to NdisIMRevertBack.

Remarks

An intermediate driver must make indications up to higher-level protocols as if from an NIC driver’s Miniport XXX functions. Attempts to simply forward indications to bound protocols directly from an intermediate driver function that receives them cause deadlocks.

For example, after a successful call to this function, the Protocol XXX function of an NDIS intermediate driver can safely call NdisM XXX functions commonly called from the MiniportHandleInterrupt or MiniportTimer functions of underlying NIC drivers. In particular, such a Protocol XXX function can call NdisM XXX functions, such as NdisMIndicateReceivePacket or NdisMIndicateStatus, that indicate up to higher-level protocols bound to the intermediate driver’s virtual NIC.

After a successful call to this function, an intermediate driver should call NdisIMRevertBack as quickly as possible. Until it calls NdisIMRevertBack, the execution of such a Protocol XXX function prevents other Miniport XXX functions in the same driver from running.

If this function returns FALSE, the intermediate driver should call the NdisIMQueueMiniportCallback function. The MiniportCallback function passed to NdisIMQueueMiniportCallback should do essentially the same work as the caller’s miniport-only code would have done if its call to this function had succeeded. That is, such a MiniportCallback function replaces the miniport-only code bracketed by calls to this function and NdisIMRevertBack, as well as setting up sufficient state to communicate with the nonminiport code paths of the intermediate driver.

If an NDIS intermediate driver has internal functions called by both its Protocol XXX and Miniport XXX functions, such an internal driver function cannot call this function, NdisIMRevertBack, or NdisIMQueueMiniportCallback. A call to any of these NdisIM XXX functions from a Miniport XXX code path is a fatal error.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

See Also

NdisIMRevertBack, NdisMEthIndicateReceive, NdisMIndicateReceivePacket, NdisMIndicateStatus


NdisInitAnsiString

This function initializes a counted ASCII string.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisInitAnsiString(IN OUT PNDIS_ANSI_STRING DestinationString, IN PCSTR SourceString);

Parameters

DestinationString
Pointer to a caller-allocated buffer in which this function should store the counted ASCII string.
SourceString
Pointer to a 0-terminated string with which to initialize the counted string.

Remarks

The DestinationString parameter is initialized to point to the SourceString parameter. The length and maximum length for the DestinationString are initialized to the length of the string at SourceString. If SourceString is NULL, the length is 0.

A driver that calls this function can be running at IRQL <= DISPATCH_LEVEL if the DestinationString buffer is allocated from nonpaged memory. Usually, callers are running at IRQL PASSIVE_LEVEL during driver initialization.

See Also

NdisAnsiStringToUnicodeString, NdisFreeString, NdisInitializeString, NdisInitUnicodeString, NdisUnicodeStringToAnsiString


NdisInitializeListHead

This function initializes a doubly linked, driver-maintained interlocked queue or doubly linked list.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisInitializeListHead(IN PLIST_ENTRY ListHead);

Parameters

ListHead
Pointer to driver-allocated nonpaged storage for the head of the interlocked queue or list.

Remarks

This function can be called from a MiniportInitialize function or from a protocol driver’s DriverEntry function if the driver queues requests internally. However, miniport drivers seldom set up internal queues because the NDIS library serializes requests and packets sent to miniports.

Any NDIS driver that maintains an internal queue is responsible for synchronizing driver functions’ accesses to queued entries. The NdisInterlocked XXX List functions ensure that only one driver function can access queued entries at any moment, even if the driver is running on a multiprocessor machine, because the queue is protected by a caller-supplied spin lock.

For an interlocked queue, the driver must also provide nonpaged storage for a spin lock. It must initialize the spin lock with NdisAllocateSpinLock before passing a pointer to that spin lock to any of the NdisInterlocked XXX List functions.

A driver that calls this function usually runs at IRQL PASSIVE_LEVEL because this function is commonly called at initialization.

See Also

NdisAllocateSpinLock, NdisInterlockedInsertHeadList, NdisInterlockedInsertTailList, NdisInterlockedRemoveHeadList


NdisInitializeString

This function allocates storage for and initializes a counted string in the system-default character set.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisInitializeString(IN OUT PNDIS_STRING DestinationString,
IN PUCHAR SourceString);

Parameters

DestinationString
Specifies NULL when this function is called; on return from this function, points to a buffer containing an initialized counted string.
SourceString
Pointer to a 0-terminated string with which to initialize the counted string.

Remarks

This function sets the Length and MaximumLength for the destination string and terminates the destination string with 0.

If SourceString is NULL, the lengths are set to 0.

The buffer allocated by this function should be released promptly with the NdisFreeString function.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisAnsiStringToUnicodeString, NdisEqualString, NdisFreeString, NdisInitAnsiString, NdisInitUnicodeString, NdisUnicodeStringToAnsiString


NdisInitUnicodeString

This function initializes a counted Unicode string.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisInitUnicodeString(IN OUT PNDIS_STRING DestinationString,
IN PCWSTR SourceString);

Parameters

DestinationString
Pointer to a caller-allocated buffer in which this function stores the counted Unicode string.
SourceString
Pointer to a 0-terminated string with which to initialize the counted string.

Remarks

The DestinationString parameter is initialized to point to the SourceString. The length and maximum length for DestinationString are initialized to the length of the string at SourceString. If SourceString is NULL, the length is 0.

A driver that calls this function can be running at IRQL <= DISPATCH_LEVEL if the DestinationString buffer is allocated from nonpaged memory. Usually, callers are running at IRQL PASSIVE_LEVEL during driver initialization.

See Also

NdisAnsiStringToUnicodeString, NdisFreeString, NdisInitAnsiString, NdisInitializeString, NdisUnicodeStringToAnsiString


NdisInterlockedInsertHeadList

This function inserts an entry, usually a packet, at the head of a doubly linked list so that access to the list is synchronized in a multiprocessor-safe way.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

PLIST_ENTRY NdisInterlockedInsertHeadList(
IN PLIST_ENTRY ListHead, IN PLIST_ENTRY ListEntry,
IN PNDIS_SPIN_LOCK SpinLock);

Parameters

ListHead
Pointer to the head of the doubly linked list into which an entry is to be inserted.
ListEntry
Pointer to the entry to be inserted at the head of the list.
SpinLock
Pointer to a caller-supplied spin lock, used to synchronize access to the list.

Return Values

Returns a pointer to the entry that was at the head of the queue before the specified entry was inserted. If the queue was empty, it returns NULL.

Remarks

Before calling this function, a driver must initialize the variable at ListHead with the NdisInitializeListHead function and the variable at SpinLock with the NdisAllocateSpinLock function. The driver must also provide resident storage for these variables and for its internal queue.

The caller-supplied spin lock prevents any other function from accessing the driver’s internal queue while this function is inserting the given entry, even when the driver is running on a multiprocessor machine.

This function raises IRQL to DISPATCH_LEVEL when it acquires the specified spin lock and restores the original IRQL before it returns control. Consequently, any driver function that calls this function cannot be pageable code.

Most NDIS drivers process packets in first-in, first-out (FIFO) order, so any driver that uses an interlocked queue tends to call the NdisInterlockedInsertTailList function far more frequently than this function. Such a driver usually calls this function only to requeue a packet for a retry operation.

To convert a returned value back to the address of the inserted entry, a driver can use the CONTAINING_RECORD macro.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

See Also

NdisAllocateSpinLock, NdisInitializeListHead, NdisInterlockedInsertTailList, NdisInterlockedRemoveHeadList


NdisInterlockedInsertTailList

This function inserts an entry, usually a packet, at the tail of a doubly linked list so that access to the list is synchronized in a multiprocessor-safe way.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

PLIST_ENTRY NdisInterlockedInsertTailList(IN PLIST_ENTRY ListHead,
IN PLIST_ENTRY ListEntry, IN PNDIS_SPIN_LOCK SpinLock);

Parameters

ListHead
Pointer to the head of the doubly linked list into which an entry is to be inserted.
ListEntry
Pointer to the entry to be inserted at the end of the list.
SpinLock
Pointer to a caller-supplied spin lock, used to synchronize access to the list.

Return Values

Returns a pointer to the entry that was at the tail of the queue before the specified entry was inserted. If the queue was empty, it returns NULL.

Remarks

Before calling this function, a driver must initialize the variable at ListHead with the NdisInitializeListHead function and the variable at SpinLock with the NdisAllocateSpinLock function. The driver must also provide resident storage for these variables and for its internal queue.

The caller-supplied spin lock prevents any other function from accessing the driver’s internal queue while this function is inserting the given entry, even when the driver is running on a multiprocessor machine.

This function raises IRQL to DISPATCH_LEVEL when it acquires the specified spin lock and restores the original IRQL before it returns control. Consequently, any driver function that calls this function cannot be pageable code.

To convert a returned value back to the address of the inserted entry, a driver can use the CONTAINING_RECORD macro.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

See Also

NdisAllocateSpinLock, NdisInitializeListHead, NdisInterlockedInsertHeadList, NdisInterlockedRemoveHeadList


NdisInterlockedRemoveHeadList

This function removes an entry, usually a packet, from the head of a doubly linked list so that access to the list is synchronized in a multiprocessor-safe way.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

PLIST_ENTRY NdisInterlockedRemoveHeadList(
IN PLIST_ENTRY ListHead, IN PNDIS_SPIN_LOCK SpinLock);

Parameters

ListHead
Pointer to the head of the doubly linked list from which an entry is to be removed.
SpinLock
Pointer to a caller-supplied spin lock, used to synchronize access to the list.

Return Values

Returns a pointer to the dequeued entry. If the list is empty, it returns NULL.

Remarks

Before calling any NdisInterlocked XXX List function, a driver must initialize the variable at ListHead with the NdisInitializeListHead function and the variable at SpinLock with the NdisAllocateSpinLock function. The driver must also provide resident storage for these variables and for its internal queue.

Before calling this function, entries are queued with one or more calls to the NdisInterlockedInsert XXX List functions.

The caller-supplied spin lock prevents any other function from accessing the driver’s internal queue while this function is removing an entry, even when the driver is running on a multiprocessor machine.

This function raises IRQL to DISPATCH_LEVEL when it acquires the specified spin lock and restores the original IRQL before it returns control. Consequently, any driver function that calls this function cannot be pageable code.

To convert a returned value back to the address of the inserted entry, a driver can use the CONTAINING_RECORD macro.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

See Also

NdisAllocateSpinLock, NdisInitializeListHead, NdisInterlockedInsertHeadList, NdisInterlockedInsertTailList


NdisMAllocateMapRegisters

This function reserves system resources during NIC driver initialization for subsequent busmaster DMA operations.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

NDIS_STATUS NdisMAllocateMapRegisters(
IN NDIS_HANDLE MiniportAdapterHandle, IN UINT DmaChannel,
IN BOOLEAN Dma32BitAddresses, IN ULONG PhysicalMapRegistersNeeded,
IN ULONG MaximumPhysicalMapping);

Parameters

MiniportAdapterHandle
Handle input to the MiniportInitialize function.
DmaChannel
Specifies the bus-relative DMA channel for an ISA busmaster NIC. If the NIC is on another type of I/O bus, this parameter must be 0.
Dma32BitAddresses
Specifies TRUE if the NIC is capable of using 32-bit addressing for DMA operations.
PhysicalMapRegistersNeeded
Specifies the maximum number of map registers, each mapping a discrete physical page or contiguous range within a physical page, that the NIC can use in a DMA operation. With MaximumPhysicalMapping, this parameter describes the DMA-transfer capabilities of the NIC.
MaximumPhysicalMapping
Specifies the maximum number of bytes that the NIC can transfer as a single DMA operation.

Return Values

NDIS_STATUS_SUCCESS indicates success. NDIS_STATUS_RESOURCES indicates that either the caller specified incompatible parameters when MiniportInitialize called the NdisMSetAttributesEx function or the requested number of map registers could not be allocated due to system resource constraints.

Remarks

Drivers of busmaster DMA NICs call this function from their MiniportInitialize functions.

Such a driver’s MiniportInitialize function must call NdisMSetAttributes or NdisMSetAttributesEx before it calls this function. It should call the NdisQueryMapRegisterCount function before calling this function as well.

The specified PhysicalMapRegistersNeeded is constrained by one of the following:

  • The number of physical discontiguities backing any specified virtual range for a DMA transfer that the NIC can handle.
  • The relative sizes of the NIC’s MaximumPhysicalMapping and the memory PAGE_SIZE of the current platform.
  • For a busmaster NIC, MaximumPhysicalMapping is the largest number of bytes in any virtual range described by an NDIS_BUFFER-type descriptor that can be passed subsequently to the NdisMStartBufferPhysicalMapping function.
  • The number of available map registers for the NIC’s I/O bus in the current platform.

Map registers are a limited system resource, so a miniport should never allocate more map registers than its NIC can use in a DMA transfer operation. The NdisQueryMapRegisterCount function returns the maximum number of map registers that can be allocated on the current platform for the type of I/O bus that the NIC uses. MiniportInitialize should pass the minimum of the following values for PhysicalMapRegistersNeeded to this function:

  • The result of (MaximumBytesPerTransferOfNIC / PAGE_SIZE + 1)
  • The number of physical discontiguites per virtual transfer range that the NIC can handle in any DMA transfer operation
  • The value returned by the NdisQueryMapRegisterCount function

The map registers allocated with this function are implicitly numbered from 0 through (PhysicalMapRegistersNeeded – 1). When calling the NdisMStartBufferPhysicalMapping function, the driver of a busmaster NIC specifies which map register to use in each call by specifying that map register’s 0-based index.

The driver of a busmaster DMA NIC must call this function before it calls the NdisMAllocateSharedMemory function.

Drivers of NICs that use PIO or the host DMA controller as slave devices do not call this function during initialization.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisMFreeMapRegisters, NdisMSetAttributes, NdisMSetAttributesEx, NdisQueryMapRegisterCount


NdisMCancelTimer

This function cancels a preceding call to the NdisMSetPeriodicTimer function or cancels the preceding call to the NdisMSetTimer function if the interval specified to NdisMSetTimer has not yet expired.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMCancelTimer(IN PNDIS_MINIPORT_TIMER Timer,
OUT PBOOLEAN TimerCanceled);

Parameters

Timer
Pointer to a timer object, already initialized with the NdisMInitializeTimer function and set with the NdisMSetPeriodicTimer or the NdisMSetTimer function.
TimerCancelled
Pointer to a caller-supplied variable, which this function sets to TRUE if the timer was queued and then canceled, or to FALSE if the timer either was not set or has already fired.

Remarks

All NDIS timer functions operate on an opaque timer object, for which an NIC driver must supply resident storage. The MiniportInitialize function must call NdisMInitializeTimer with a caller-supplied pointer to this storage, thus associating a driver-supplied MiniportTimer function with the timer object. MiniportInitialize must call NdisMInitializeTimer before the driver passes the Timer pointer to any other NDIS timer function.

Drivers of NICs that do not generate interrupts have a polling MiniportTimer function to monitor the NIC state for incoming receives and for send completions.

Calls to the NdisMSet XXX Timer functions insert the timer object in the system timer queue. Calls to this function dequeue the timer object if it is currently queued. Only one instantiation of a particular timer object can be queued at any moment.

A call to this function while the timer object designated by Timer is queued removes the timer object from the queue, thus canceling the execution of the associated MiniportTimer function.

A subsequent call to NdisMSetTimer or NdisMSetPeriodicTimer requeues the timer object so that the MiniportTimer function runs again when the specified interval expires.

A call to this function can occur just after a timer has fired but before the associated MiniportTimer function is run. Usually, MiniportTimer sets a state variable immediately on entry to indicate that it is running. When another miniport function calls this function, it can check such a TimerCancelled variable on return from this call to determine whether its call to this function also canceled execution of MiniportTimer.

A call to this function while MiniportTimer is running has no effect on the execution of MiniportTimer. It continues to run until it returns control.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

SeeAlso

NdisMInitializeTimer, NdisMSetPeriodicTimer, NdisMSetTimer


NdisMDeregisterAdapterShutdownHandler

This function removes an NIC-driver-supplied MiniportShutdown function from the list of registered shutdown handlers to be called.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMDeregisterAdapterShutdownHandler(
IN NDIS_HANDLE MiniportHandle);

Parameters

MiniportHandle
Handle originally input to the MiniportInitialize function.

Remarks

Currently, this function is a stub that does no work. Future versions of Windows CE may implement this function.


NdisMDeregisterInterrupt

This function stops a Miniport’s interrupt service routine (ISR) from being called to handle NIC interrupts.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMDeregisterInterrupt(
IN PNDIS_MINIPORT_INTERRUPT Interrupt);

Parameters

Interrupt
Pointer to an interrupt object previously registered with the NdisMRegisterInterrupt function.

Remarks

This function releases the association between the initialized interrupt object at Interrupt and the caller’s MiniportISR function. It also releases the driver’s claim on the interrupt vector or level in the registry.

This function can be called from the MiniportInitialize or the MiniportHalt function only if MiniportInitialize previously made a successful call to NdisMRegisterInterrupt.

The miniport should disable its NIC from generating interrupts before it calls this function. After this function returns control, the miniport cannot call the NdisMSynchronizeWithInterrupt function.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisMRegisterInterrupt, NdisMSynchronizeWithInterrupt


NdisMDeregisterIoPortRange

This function releases a mapping that was set up with the NdisMRegisterIoPortRange function during driver initialization.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMDeregisterIoPortRange(
IN NDIS_HANDLE MiniportAdapterHandle, IN UINT InitialPort,
IN UINT NumberOfPorts, IN PVOID PortOffset);

Parameters

MiniportAdapterHandle
Handle input to the MiniportInitialize function.
InitialPort
Specifies the bus-relative address of the first port in the range of ports.
NumberOfPorts
Specifies the number of ports in the range.
PortOffset
Specifies the mapped base port address returned by the NdisMRegisterIoPortRange function.

Remarks

The miniport must pass the same InitialPort and NumberOfPorts parameters to this function that were passed when the MiniportInitialize function called the NdisMRegisterIoPortRange function to get the mapped PortOffset value. That is, a miniport cannot call this function to release a subrange of a mapped port range.

This function can be called from the MiniportInitialize or the MiniportHalt function only if MiniportInitialize previously made a successful call to the NdisMRegisterIoPortRange function.

This function also releases the driver’s claim on the I/O port range in the registry.

After it calls NdisMRegisterIoPortRange, the miniport can no longer access the NIC’s port range with calls to the NdisRaw XXX Port XXX functions.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisMRegisterIoPortRange


NdisMEthIndicateReceive

This function notifies NDIS that an Ethernet packet, or some initial look-ahead portion of the packet, has arrived so that NDIS can forward the packet to bound protocols.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMEthIndicateReceive(
IN NDIS_HANDLE MiniportAdapterHandle, IN NDIS_HANDLE MiniportReceiveContext, IN PVOID HeaderBuffer, IN UINT HeaderBufferSize, IN PVOID LookaheadBuffer, IN UINT LookaheadBufferSize,
IN UINT PacketSize);

Parameters

MiniportAdapterHandle
Handle originally input to the MiniportInitialize function.
MiniportReceiveContext
Context handle supplied by the caller. NDIS returns this handle as an input parameter to the MiniportTransferData function if it is called. The miniport can use the context area designated by this handle to determine which packet, on which NIC, is being received.
HeaderBuffer
Specifies the base virtual address of the buffered packet header.
HeaderBufferSize
Specifies the size, in bytes, of the packet header.
LookaheadBuffer
Specifies the base virtual address of a buffer containing the initial LookaheadBufferSize bytes of the data in the packet.
LookaheadBufferSize
Specifies the size, in bytes, of the look-ahead buffer. This value must be at least as large as the look-ahead size set when the MiniportSetInformation function was called with OID_GEN_CURRENT_LOOKAHEAD, or as large as the packet, whichever is smaller. When the packet is smaller than the look ahead size, the look-ahead buffer contains the entire frame.

A miniport can and should set this parameter to something larger than the minimum required if sufficient received data is available on its NIC.

PacketSize
Specifies the size, in bytes, of the received packet data. This value does not include the HeaderBufferSize.

When this parameter is larger than the specified LookaheadBufferSize, a protocol driver call to the NdisTransferData function causes a subsequent call to the MiniportTransferData function, which transfers the remaining data in the packet.

Remarks

A miniport calls this function if it designates its NIC as of type NdisMedium802_3 or NdisMediumDix in response to the OID_GEN_MEDIA_IN_USE query, unless the miniport indicates receives with the NdisMIndicateReceivePacket function.

When a miniport calls this function, NDIS passes a pointer to the header of the packet and a pointer to some or all of the data in the packet to the ProtocolReceive function(s) of bound protocol driver(s). Each protocol that receives the indication can do the following:

  • Inspect the header and data in the packet to decide whether the indication is of interest to the protocol’s client(s).
  • If it is, copy as much of the header or data as is visible into protocol-allocated memory with the NdisMoveMemory function.
  • Get the remaining data, if any, for the indication by allocating a packet descriptor with sufficient chained buffer descriptors and calling the NdisTransferData function. The call to NdisTransferData causes the NIC driver’s MiniportTransferData function to copy the data into the protocol-supplied packet.

For any protocol driver that receives an indication through this function, the HeaderBuffer and LookaheadBuffer parameters are valid only during the current call to its ProtocolReceive function, and these buffers are read-only. A protocol driver cannot retain a pointer to the indicated packet with these associated buffers, nor can it retain any pointers to these buffers for later use. Any data that a protocol driver needs from such a packet must be copied and saved during the receive indication.

The data in the header is the same as that received on the NIC. A miniport need not remove any headers or trailers from the data its NIC receives.

The transmitting driver adds padding to any packet that is too short for the requirements of the medium. The receiving miniport can include such padding in the data and length that it subsequently indicates. Each bound protocol is responsible for detecting any such padding and ignoring it.

A driver that calls this function runs at IRQL DISPATCH_LEVEL.

See Also

NdisMEthIndicateReceiveComplete, NdisMIndicateReceivePacket, NdisMoveMemory, NdisTransferData


NdisMEthIndicateReceiveComplete

This function notifies NDIS that an Ethernet receive packet, identified in a preceding call to the NdisMEthIndicateReceive function, has been fully transferred by the NIC so that NDIS can notify the appropriate bound protocols.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMEthIndicateReceiveComplete(
IN NDIS_HANDLE MiniportAdapterHandle);

Parameters

MiniportAdapterHandle
Handle originally input to the MiniportInitialize function.

Remarks

After any Ethernet receive indication, a miniport eventually must call this function to indicate the end of the transfer operation over the net, even if a particular packet is accepted by no bound protocol.

This function both indicates the completion of a transfer operation for a receive and notifies any bound protocol that has already consumed the initial indication that it can begin postprocessing the received data.

When a miniport calls this function, NDIS indicates the completion of the receive operation to each such protocol by calling its ProtocolReceiveComplete function.

ProtocolReceiveComplete functions need not operate under the severe time constraints of the corresponding ProtocolReceive functions. However, another receive indication to the ProtocolReceive function can come in while the ProtocolReceiveComplete function is running.

A miniport need not call this function in one-to-one correspondence with its calls to the NdisMEthIndicateReceive function. That is, an NIC driver can issue a single receive-complete indication for some number of receive indications, particularly when network traffic is high. For example, when a miniport is continually indicating receives from the same source, it might call this function once for every ten indications. On the other hand, a miniport might call this function once for each indication when network traffic is low so that the driver can promptly regain ownership of the memory that it allocated for receives.

A driver that calls this function runs at IRQL DISPATCH_LEVEL.

See Also

NdisMEthIndicateReceive


NdisMFreeMapRegisters

This function releases a set of map registers that were allocated during initialization with NdisMAllocateMapRegisters by a busmaster DMA NIC driver.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMFreeMapRegisters(
IN NDIS_HANDLE MiniportAdapterHandle);

Parameters

MiniportAdapterHandle
Handle originally input to the MiniportInitialize function.

Remarks

If it has already made a successful call to the NdisMAllocateMapRegisters function, the NIC driver of a busmaster DMA device calls this function if any of the following occurs:

  • Its MiniportInitialize function is unable to initialize the NIC, so this function must release all existing claims on hardware resources for that NIC before it returns control.
  • The NIC for which the miniport allocated the map registers is being removed.
  • The driver is being unloaded, either because the system is shutting down or because the user reconfigured the network components used in the machine.

As soon as it calls this function, the driver of a busmaster DMA NIC can no longer use the map registers that it previously allocated.

This function can be called only from an NIC driver’s MiniportInitialize and MiniportHalt functions.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisMAllocateMapRegisters


NdisMIndicateReceivePacket

This function notifies NDIS that an array of received packets is available to be forwarded to the appropriate bound protocol driver(s).

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMIndicateReceivePacket(
IN NDIS_HANDLE MiniportAdapterHandle,
IN PPNDIS_PACKET ReceivePackets, IN UINT NumberOfPackets);

Parameters

MiniportAdapterHandle
Handle originally input to the MiniportInitialize function.
ReceivePackets
Pointer to an array of packet descriptor pointers, with each descriptor set up by the caller to specify the received data.
NumberOfPackets
Specifies how many pointers are in the array at ReceivePackets. The value must be at least 1.

Remarks

Drivers of busmaster DMA NICs are most likely to show significant gains in performance by making multipacket receive indications with this function. However, drivers that indicate out-of-band data with receive packets, such as packet priority and/or time stamps, can also call this function with a single packet at a time.

When a miniport calls this function, NDIS passes each pointer at ReceivePackets separately, in the miniport-determined order, to the ProtocolReceivePacket function(s) of bound protocol(s) that export this function. To other bound protocols, NDIS passes each packet pointer to the ProtocolReceive function(s).

If the miniport did not designate its NIC’s medium as a type for which the system supplies a filter package in response to the OID_GEN_MEDIA_IN_USE query, NDIS forwards that driver’s receive indications to all bound protocol drivers that export a ProtocolReceivePackets function. Otherwise, NDIS automatically applies the appropriate filter library to the miniport’s receive indications.

Any caller of this function must first set up the packet array, as follows:

  • Each element is the pointer to a packet descriptor, which the caller must allocate from a packet pool. Each packet descriptor can have at most 16 bytes in its ProtocolReserved section.
  • All buffer descriptors chained to such a packet descriptor must be allocated from a buffer pool. The miniport must call the NdisAdjustBufferLength function with any buffer descriptor mapping a receive buffer on the NIC that contains less received data than the full range of the receive buffer so that the buffer descriptor maps only the received data for the indication. The NIC driver must readjust the mapping with NdisAdjustBufferLength when it regains ownership of such a buffer descriptor, as well.
  • If the miniport indicates time stamps for received packets, it must set the TimeReceived and/or TimeSent members in the NDIS_PACKET_OOB_DATA structure associated with the packet descriptor using the NDIS_SET_PACKET_TIME_RECEIVED and/or NDIS_SET_PACKET_TIME_SENT macros. It can call the NdisGetCurrentSystemTime function once to set the receive time stamp for all packets of a particular packet array.
  • The HeaderSize in the out-of-band data block must match the header size of each received packet for the medium. For example, a driver that selects Ethernet as its preferred medium at initialization would initialize the NDIS_PACKET_OOB_DATA structure HeaderSize to 14 when it allocates the packet descriptor.
  • If the driver indicates additional out-of-band information with receives, it must set the SizeMediaSpecificInfo to the number of bytes of information supplied in the caller-allocated buffer at MediaSpecificInformation. The miniport can use the NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO macro to set these values. Otherwise, SizeMediaSpecificInfo should be 0, and MediaSpecificInformation should be NULL.
  • The miniport can set the Status member of the out-of-band data block to NDIS_STATUS_RESOURCES if it needs to retain ownership of the packet descriptor and buffer descriptors of some element(s) in a particular indication. Setting this status for a packet implicitly sets the same status for all subsequent packets of the indicated array. Setting NDIS_STATUS_RESOURCES forces NDIS to indicate each such packet, one at a time, to bound protocols’ ProtocolReceive functions, thus forcing each protocol to copy the packet data and release each packet to be returned back to the miniport. Otherwise, the call to this function gives interested protocols exclusive, read-only access to the buffers chained to each packet until either of the following occurs:
    • The Status in the out-of-band data block is set to NDIS_STATUS_SUCCESS on return from this function. In this case, the miniport regains ownership of the packet descriptor and all buffers chained to the packet. It can prepare these descriptors immediately for reuse in subsequent receive indications.
    • The Status is set to NDIS_STATUS_PENDING on return from this function. In this case, the driver’s MiniportReturnPacket function is called when the miniport regains ownership of the packet and buffer descriptors. It can then prepare these descriptors for reuse in subsequent receive indications.

The miniport should use NDIS_GET_PACKET_STATUS to determine whether it has regained ownership of indicated packets when this function returns control.

When the miniport regains ownership of an indicated packet descriptor, it prepares the associated out-of-band data block for reuse by passing the pointer returned by NDIS_OOB_DATA_FROM_PACKET to the NdisZeroMemory function. As an alternative, the miniport can simply reset the relevant member(s) at the subsequent receive with the NDIS_SET_PACKET_XXX macro(s) or with the pointer returned by NDIS_OOB_DATA_FROM_PACKET.

A miniport must not pass a packet descriptor pointer to NdisZeroMemory. Doing this destroys the packet descriptor, rendering it unusable for subsequent indications. To clear the associated out-of-band data block, the driver must pass the pointer returned by NDIS_OOB_DATA_FROM_PACKET.

Packet arrays passed to this function can be allocated on the stack, which cannot be paged out in the NDIS library’s receive-indication code path.

When NDIS calls the ProtocolReceive function of a driver that exports a ProtocolReceivePacket function, ProtocolReceive can call NdisQueryReceiveInformation to retrieve the out-of-band information associated with an incoming packet that was indicated as part of a packet array.

Any miniport that calls this function must indicate full packets. Consequently, such a driver has no MiniportTransferData function.

A driver that calls this function can run at IRQL <= DISPATCH_LEVEL, but usually callers are running at DISPATCH_LEVEL.

See Also

NdisAdjustBufferLength, NdisAllocateBuffer, NdisAllocatePacket, NdisChainBufferAtBack, NdisChainBufferAtFront, NdisZeroMemory


NdisMIndicateStatus

This function indicates changes in the status of an NIC to higher-level NDIS drivers.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMIndicateStatus(IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_STATUS GeneralStatus, IN PVOID StatusBuffer,
IN UINT StatusBufferSize);

Parameters

MiniportAdapterHandle
Handle originally input to the MiniportInitialize function.
GeneralStatus
Specifies the NDIS_STATUS_XXX value that indicates the general change in status for the NIC.
StatusBuffer
Pointer to a caller-allocated buffer containing data that is medium-specific and dependent on the value of GeneralStatus. It indicates detailed information about the change in status.
StatusBufferSize
Specifies the size, in bytes, of the buffer at StatusBuffer.

Remarks

When a miniport calls this function, NDIS calls each bound protocol’s ProtocolStatus function. This allows a bound protocol driver or, possibly, the configuration manager to log the change in status of an underlying NIC or to take corrective action. For example, a protocol might call the NdisReset function, depending on the NDIS_STATUS_XXX indicated.

When a miniport calls this function to report a change in NIC status, NDIS can call the MiniportReset function to try to restore the NIC to a working condition. In these circumstances, NDIS can call bound protocols only with NDIS_STATUS_RESET_START and later with NDIS_STATUS_RESET_END, rather than with the GeneralStatus indicated by the miniport.

This function provides two pieces of information:

  • An overall status value indicating the general change in status.
  • A specific reason for the general change, which can be network-specific. For example, ring-insertion failures are particular to Token Ring (802.5) networks, but are irrelevant to Ethernet (802.3) NICs and their drivers.

A miniport can also call this function to indicate problems, such as cables that have been accidentally removed and then reinserted, or a ring that has temporarily failed. For example, both the following conditions might occur:

  • The miniport calls this function with NDIS_STATUS_RING_STATUS.
  • The StatusBuffer contains one of the following status values:
    • NDIS_RING_LOBE_WIRE_FAULT
    • NDIS_RING_HARD_ERROR
    • NDIS_RING_SIGNAL_LOSS

After such a change in status has been signaled with an indication, any associated thresholds or statistics counters remain unchanged.

Most WAN NIC drivers indicate status with some special status codes and buffer contents. These status indications are generated by WAN NIC drivers, and NDIS protocol drivers bound to such a miniport can ignore these indications. However, processing these indications correctly usually results in improved performance for protocols and for WAN NIC drivers.

The following four types of WAN-specific indications can be sent to bound protocol drivers with this function:

  • Line up
  • Line down
  • Fragment
  • TAPI line event

A WAN miniport makes a line-up indication whenever a new link becomes active. Until this occurs, the NIC accepts frames and lets them succeed or fail, but it is unlikely that they are received by any remote. Until this occurs, protocols should reduce their timers and retry counts so as to quickly fail any outgoing connection attempts.

The WAN miniport makes this indication with this function before it returns from the OID_TAPI_GET_ID request.

The status code for the line-up indication is NDIS_STATUS_WAN_LINE_UP. The buffer at StatusBuffer is formatted as an NDIS_MAC_LINE_UP structure.

A WAN miniport makes a line-down indication whenever a link goes down. When this occurs, bound protocols should reduce their timers and retry counts until the next line-up indication.

The status code for the line-down indication is NDIS_STATUS_WAN_LINE_DOWN. The buffer at StatusBuffer is formatted as an NDIS_MAC_LINE_DOWN structure.

A WAN miniport makes a fragment indication whenever it receives a partial packet from the remote node. When this occurs, a bound protocol sends frames to the remote that notify it of this situation, rather than waiting for a time-out to occur.

The status code for the fragment indication is NDIS_STATUS_WAN_FRAGMENT. The buffer at StatusBuffer is formatted as an NDIS_MAC_FRAGMENT structure.

NDISWAN monitors drop packets by counting the number of fragment indications on each link.

A WAN miniport must use a GeneralStatus value of NDIS_STATUS_TAPI_INDICATION for TAPI status indications. The buffer at StatusBuffer is formatted as an NDIS_TAPI_EVENT structure.

A driver that calls this function runs at IRQL DISPATCH_LEVEL.

See Also

NdisMIndicateStatusComplete


NdisMIndicateStatusComplete

This function notifies NDIS, or NDISWAN, that the NIC driver, which has called the NdisMIndicateStatus function one or more times to indicate hardware anomalies or run-time state changes in the NIC, is ready to resume standard device I/O operations.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMIndicateStatusComplete(
IN NDIS_HANDLE MiniportAdapterHandle);

Parameters

MiniportAdapterHandle
Handle originally input to the MiniportInitialize function.

Remarks

When a miniport calls this function, NDIS calls the ProtocolStatusComplete function(s) of bound protocol(s) that were previously notified of the immediately preceding state change(s) in the underlying NIC with calls to their ProtocolStatus functions.

A miniport eventually must call this function after it calls the NdisMIndicateStatus function. However, a miniport need not deliver this function indications in one-to-one correspondence with its NdisMIndicateStatus indications. It can choose to issue a single status-complete indication for several status indications that have occurred, particularly when network traffic is high.

A protocol driver writer should assume that interrupts are enabled on the NIC while ProtocolStatusComplete is running. A protocol driver writer should also assume that ProtocolStatus is re-entrant while ProtocolStatusComplete is running, particularly on an SMP platform.

A driver that calls this function runs at IRQL DISPATCH_LEVEL.

See Also

NdisMIndicateStatus


NdisMInitializeTimer

This function initializes a timer object associated with a driver’s MiniportTimer function.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMInitializeTimer(IN OUT PNDIS_MINIPORT_TIMER Timer, IN NDIS_HANDLE MiniportAdapterHandle,
IN PNDIS_TIMER_FUNCTION TimerFunction,
IN PVOID FunctionContext);

Parameters

Timer
Pointer to caller-supplied resident storage for a timer object. The timer object is opaque to the caller, but, when it has been initialized, this pointer is a required parameter to the NDIS timer functions.
MiniportAdapterHandle
Handle input to the MiniportInitialize function.
TimerFunction
Specifies the entry point of a caller-supplied MiniportTimer function.
FunctionContext
Pointer to a caller-supplied context area to be passed to the given MiniportTimer function when it is called.

Remarks

MiniportInitialize must call this function to set up the driver’s MiniportTimer function(s), if any. MiniportInitialize must call this function before the driver passes the MiniportTimer pointer to any other NDIS timer function.

Drivers of NICs that do not generate interrupts initialize at least one timer object for a polling MiniportTimer function that monitors the NIC state for incoming receives and for send completions.

Calls to the NDIS timer functions insert the timer object in the system timer queue. Calls to the NdisMCancelTimer function dequeue the timer object if it is currently queued. Only one instantiation of a particular timer object can be queued at any given moment.

When a driver calls the NdisMSetTimer function, the timer object at Timer is queued until the interval specified in the call expires. When it does, the timer object is dequeued and the caller-supplied TimerFunction is run once at IRQL DISPATCH_LEVEL as soon as a processor becomes available. When a driver calls the NdisMSetPeriodicTimer function, the timer object is dequeued and the caller-supplied TimerFunction is run when the given interval expires. However, the timer object is automatically requeued for the same fixed interval, so MiniportTimer runs periodically, also at IRQL DISPATCH_LEVEL.

MiniportInitialize can call this function more than once to initialize more than one timer object, each associated with a distinct MiniportTimer function. For example, an NIC driver might have one MiniportTimer function that polls the NIC state periodically and another that the miniport uses only to time-out a particular operation on its NIC. Each such MiniportTimer function has different functionality, and each such function should be associated with a different timer object by calling this function from MiniportInitialize.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisMCancelTimer, NdisMSetPeriodicTimer, NdisMSetTimer


NdisMInitializeWrapper

This function notifies NDIS that a new miniport is initializing.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMInitializeWrapper(OUT PNDIS_HANDLE NdisWrapperHandle, IN PVOID SystemSpecific1, IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3);

Parameters

NdisWrapperHandle
Pointer to a caller-supplied variable in which NDIS returns a handle that represents itself.
SystemSpecific1
Pointer to a system-specific type.
SystemSpecific2
Pointer to a system-specific type.
SystemSpecific3
Pointer to a system-specific type.

Remarks

An NIC driver or intermediate driver must call this function before it calls any other Ndis XXX function. Usually, this call is the initial action of any NIC driver’s DriverEntry function, which calls the NdisMRegisterMiniport or the NdisIMRegisterLayeredMiniport function with the returned NdisWrapperHandle next. NDIS intermediate drivers must also call this function from the DriverEntry function, and then call NdisMRegisterMiniport or NdisIMRegisterLayeredMiniport with the returned NdisWrapperHandle.

Such a driver’s subsequent calls to Ndis XXX initialization and configuration functions must pass the NdisWrapperHandle as a parameter. Consequently, it is an input parameter to MiniportInitialize.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisMRegisterMiniport, NdisTerminateWrapper


NdisMMapIoSpace

This function maps a specified bus-relative range of physical addresses or registers onto a system-space virtual range of addresses.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

NDIS_STATUS NdisMMapIoSpace(OUT PVOID *VirtualAddress,
IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_PHYSICAL_ADDRESS PhysicalAddress, IN UINT Length);

Parameters

Virtual Address
Pointer to a caller-supplied variable that is set to the converted virtual address if the call is successful.
MiniportAdapterHandle
Handle input to the MiniportInitialize function.
PhysicalAddress
Specifies the bus-relative base physical address of the device memory range to be mapped.
Length
Specifies the number of bytes to be mapped.

Return Values

NDIS_STATUS_SUCCESS indicates success. One of the following values indicates failure:

NDIS_STATUS_RESOURCE_CONFLICT
An attempt to claim the device memory range in the registry has failed, possibly because another driver has already claimed the range for its device. This function logs an error if this occurs.
NDIS_STATUS_RESOURCES
The memory could not be mapped or sufficient virtual memory could not be allocated.
NDIS_STATUS_FAILURE
Either the bus type or bus number is out of range, or the specified PhysicalAddress and Length were invalid, possibly not within the I/O space of the current platform.

Remarks

This function is called by drivers of NICs that have on-board memory or a bank of device registers appearing in the I/O space of the host. For example, the driver of an NIC that uses PI/O calls this function.

A successful call to this function claims hardware resources in the registry for the driver’s NIC. Consequently, only MiniportInitialize functions call this function.

This function sets the variable at VirtualAddress to NULL if it does not return NDIS_STATUS_SUCCESS.

MiniportInitialize gets the PhysicalAddress value either from the driver’s Parameters registry key or by calling a bus-type-specific Ndis XXX configuration function. The specified physical address range must fall within the I/O space of the current platform. It is a programming error to call this function with a host physical memory address.

A miniport must call the reciprocal NdisMUnmapIoSpace function to release its claim on system resources if MiniportInitialize subsequently fails to initialize the NIC, if its NIC is removed from the machine, and/or when the driver is unloading.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisMUnmapIoSpace, NdisOpenConfiguration, NdisReadPciSlotInformation


NdisMoveFromMappedMemory

This function copies data from device memory that was mapped during initialization with the NdisMMapIoSpace function to a system-space buffer.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMoveFromMappedMemory(OUT PVOID Destination,
IN PVOID Source, IN ULONG Length);

Parameters

Destination
Pointer to a system-space buffer into which this function copies data from mapped device memory. This buffer must be at least Length bytes in size.
Source
Specifies the base virtual address within mapped device memory from which to copy the data. This address must fall at least Length bytes from the end of the mapped range.
Length
Specifies the number of bytes to copy.

Remarks

An NIC driver calls this function to copy data from NIC memory into a buffer in the host, as, for example, when transferring received data into a protocol-supplied buffer or miniport-allocated staging buffer.

Both the Source and Destination pointers are virtual addresses. The virtual range specified by Source and Length must fall within a range of device memory that was mapped during initialization with the NdisMMapIoSpace function.

A driver that calls this function can run at any IRQL when the given Source and Destination are resident. Otherwise, callers must be running at IRQL < DISPATCH_LEVEL, as, for example if the Destination address is on the stack.

See Also

NdisAllocateMemory, NdisMMapIoSpace, NdisMoveMappedMemory, NdisMoveToMappedMemory


NdisMoveMappedMemory

This function copies data from one location to another within a device memory range that was mapped during initialization with the NdisMMapIoSpace function.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMoveMappedMemory(OUT PVOID Destination,
IN PVOID Source, IN ULONG Length);

Parameters

Destination
Specifies the base virtual address within the mapped range at which the data should be copied.
Source
Specifies the base virtual address within the mapped range at which the copy should begin.
Length
Specifies the number of bytes to copy.

Remarks

Both the Source and Destination pointers are virtual addresses. The virtual ranges specified both by Destination and Length and by Source and Length must fall within the range that was mapped during initialization with NdisMMapIoSpace.

A driver that calls this function can run at any IRQL.

See Also

NdisAllocateMemory, NdisMMapIoSpace, NdisMoveFromMappedMemory, NdisMoveMemory, NdisMoveToMappedMemory


NdisMoveMemory

This function copies a specified number of bytes from one caller-supplied location to another.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMoveMemory(OUT PVOID Destination, IN PVOID Source,
IN ULONG Length);

Parameters

Destination
Pointer to a system-space buffer that is the destination of the move. This buffer must be at least Length bytes in size.
Source
Pointer to a system-space buffer from which this function copies the data to the destination buffer. This buffer must be at least Length bytes in size.
Length
Specifies the number of bytes to copy.

Remarks

Both Source and Destination are virtual addresses.

If either address falls within a range of device memory that was mapped with the NdisMMapIoSpace function, an NIC driver calls one of the Ndis XXX MappedMemory functions instead of this function.

The range specified by Source and Length cannot overlap the Destination range.

A driver that calls this function can run at any IRQL if the given Source and Destination are resident. Otherwise, a driver that calls this function must be running at IRQL < DISPATCH_LEVEL, as, for example if either address is on the stack.

See Also

NdisAllocateMemory, NdisMMapIoSpace, NdisMoveFromMappedMemory, NdisMoveMappedMemory, NdisMoveToMappedMemory


NdisMoveToMappedMemory

This function copies data from a system-space buffer to device memory that was mapped during initialization with the NdisMMapIoSpace function.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMoveToMappedMemory(OUT PVOID Destination,
IN PVOID Source, IN ULONG Length);

Parameters

Destination
Specifies the base virtual address within a mapped device memory range where the copy should begin. This address must fall at least Length bytes from the end of the mapped range.
Source
Pointer to a system-space buffer from which this function copies data to the destination range. This buffer must be at least Length bytes in size.
Length
Specifies the number of bytes to copy.

Remarks

An NIC driver calls this function to copy data from a buffer in the host to mapped device memory, as, for example, when transferring data from a protocol-supplied buffer or miniport-allocated staging buffer to the NIC for a transmit.

Both the Source and Destination pointers are virtual addresses. The virtual range specified by Destination and Length must fall within a range that was mapped with the NdisMMapIoSpace function.

A driver that calls this function can run at any IRQL when the given Source and Destination are resident. Otherwise, callers must be running at IRQL < DISPATCH_LEVEL, as, for example if the Source address is on the stack.

See Also

NdisAllocateMemory, NdisMMapIoSpace, NdisMoveFromMappedMemory, NdisMoveMappedMemory, NdisMoveMemory


NdisMPciAssignResources

This function returns a list of bus-relative hardware resources, such as IRQ, I/O ports, and device memory ranges, claimed in the registry for a PCI NIC.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

NDIS_STATUS NdisMPciAssignResources(
IN NDIS_HANDLE MiniportHandle, IN ULONG SlotNumber,
OUT PNDIS_RESOURCE_LIST *AssignedResources);

Parameters

MiniportHandle
Specifies the MiniportAdapterHandle passed in to the MiniportInitialize function and to most other Miniport XXX functions.
SlotNumber
Specifies the slot number of the driver’s NIC on the PCI bus.
AssignedResources
Pointer to a list of the hardware resources the NIC can use.

Return Values

Returns NDIS_STATUS_SUCCESS.

Remarks

This function claims a set of hardware resources in the registry for a miniport’s PCI NIC to use, thus preventing conflicting claims on the same resources from other devices in the machine.

The buffer specified at AssignedResources is formatted as an NDIS_RESOURCE_LIST structure, which is equivalent to the CM_PARTIAL_RESOURCE_LIST structure on Windows NT platforms.

The bus-relative configuration parameters returned in this buffer can be used in the MiniportInitialize function’s subsequent calls to Ndis XXX functions such as NdisMRegisterInterrupt, NdisMMapIoSpace, and/or NdisMRegisterIoPortRange.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisMMapIoSpace, NdisReadPciSlotInformation


NdisMQueryInformationComplete

This function indicates that a prior call to the MiniportQueryInformation function, which returned NDIS_STATUS_PENDING, has completed.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMQueryInformationComplete(
IN NDIS_HANDLE MiniportAdapterHandle, IN NDIS_STATUS Status);

Parameters

MiniportAdapterHandle
Handle originally input to the MiniportInitialize function.
Status
Specifies the return value for the completed request originally passed to the MiniportQueryInformation function.

Remarks

A call to this function causes NDIS to return the completed query request to the ProtocolRequestComplete function of the driver that originally called the NdisRequest function.

Before it calls this function, a miniport supplies the OID-specific information originally requested from its MiniportQueryInformation function. That is, the driver sets the appropriate values at BytesWritten and/or BytesNeeded and provides as much of the requested data as possible in the buffer at InformationBuffer.

A driver that calls this function runs at IRQL DISPATCH_LEVEL.

See Also

NdisRequest


NdisMRegisterAdapterShutdownHandler

This function registers an NIC-driver-supplied MiniportShutdown function to be called when the system is shutting down.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMRegisterAdapterShutdownHandler(
IN NDIS_HANDLE MiniportHandle, IN PVOID ShutdownContext,
IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler);

Parameters

MiniportHandle
Specifies the handle input to the MiniportInitialize function.
ShutdownContext
Pointer to a driver-determined context area. This pointer is passed to the function at ShutdownHandler when it is called.
ShutdownHandler
Specifies the entry point of the caller’s MiniportShutdown function.

Remarks

The Windows CE version of this function is a stub which does no work. It may be more fully implemented in later versions of Windows CE.


NdisMRegisterInterrupt

This function sets up a mapping between an NIC driver’s MiniportISR and MiniportHandleInterrupt functions, already registered with NdisMRegisterMiniport, and the bus-relative vector and level on which its NIC interrupts.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

NDIS_STATUS NdisMRegisterInterrupt(
OUT PNDIS_MINIPORT_INTERRUPT Interrupt,
IN NDIS_HANDLE MiniportAdapterHandle, IN UINT InterruptVector,
IN UINT InterruptLevel, IN BOOLEAN RequestIsr,
IN BOOLEAN SharedInterrupt,
IN NDIS_INTERRUPT_MODE InterruptMode);

Parameters

Interrupt
Pointer to caller-allocated resident memory containing an opaque interrupt object, which this function initializes and for which it returns a handle that the miniport uses in subsequent calls to the NdisMSynchronizeWithInterrupt function.
MiniportAdapterHandle
Handle input to the MiniportInitialize function.
InterruptVector
Specifies the bus-relative vector number used by the NIC.
InterruptLevel
Specifies the bus-relative DIRQL for the interrupt. This value is almost always the same as that of InterruptVector.
RequestIsr
Specifies TRUE if the MiniportISR function should be called each time the NIC interrupts. If the NIC can share an interrupt with other devices on the I/O bus, this parameter must be set to TRUE.
SharedInterrupt
Specifies TRUE if other devices on the I/O bus can use this interrupt line. If this parameter is set to FALSE and another device has already claimed the specified interrupt vector in the registry, this function fails.
InterruptMode
Specifies the type of interrupt that the NIC generates as one of the following values:
NdisInterruptLatched
Interrupts are triggered by a transition from low to high on the interrupt line.
NdisInterruptLevelSensitive
Interrupts are active as long as the interrupt line is asserted.

Return Values

Returns one of the following values:

NDIS_STATUS_SUCCESS
NDIS initialized the interrupt object and returned a valid Interrupt handle, claimed hardware resources in the registry for the NIC, such as the specified vector if the NIC does not share an IRQ, and set up the MiniportISR or MiniportDisableInterrupt and associated MiniportHandleInterrupt functions to be called when an interrupt occurs as requested in the call to this function.
NDIS_STATUS_RESOURCE_CONFLICT
An attempt to claim the vector or level in the registry has failed, possibly because another driver already claimed the interrupt for its device. This function logs an error if this occurs.
NDIS_STATUS_RESOURCES
NDIS could not allocate sufficient memory to claim resources in the registry for the NIC.
NDIS_STATUS_FAILURE
The attempt to initialize the interrupt object failed, possibly due to another driver’s prior claim on the InterruptVector or InterruptLevel in the registry.

Remarks

An NIC driver must call this function from its MiniportInitialize function if its NIC generates interrupts. The driver of an NIC that does not generate interrupts calls the NdisMInitializeTimer and NdisMSetPeriodicTimer functions instead of this function.

MiniportInitialize must call NdisMSetAttributes or NdisMSetAttributesEx before calling this function.

MiniportInitialize obtains the bus-relative values passed to this function either from the registry or by calling a bus-type-specific Ndis XXX configuration function.

If its call to this function fails, MiniportInitialize releases all resources that it already allocated for its NIC, and then fails initialization for that NIC.

This function distinguishes between the InterruptVector and the InterruptLevel. The InterruptVector is the interrupt line that the card asserts to interrupt the system, and the InterruptLevel is the hardware priority, that is, the DIRQL, of that interrupt assigned by the system. Usually, these values can be assumed to be equal unless the driver writer knows that they are different for a particular NIC or unless the miniport controls more than multiple NICs that share resources in the current platform.

If its NIC can share an IRQ with other devices on the I/O bus, the caller of this function must set both the SharedInterrupt and RequestIsr parameters to TRUE. Such an NIC driver’s MiniportISR function can be called when no interrupt for the NIC is outstanding. In these circumstances, MiniportISR returns FALSE as soon as possible, indicating that the interrupt was not recognized and should leave interrupts enabled on its NIC.

When interrupts are enabled on the NIC, a driver’s MiniportISR function can be called at any time following a successful call to this function, even during initialization. Such a driver’s MiniportInitialize function should not call this function until it has set up all state that the driver needs to handle an interrupt. The MiniportHandleInterrupt function is not queued for subsequent execution if the driver’s MiniportInitialize function is currently executing and an interrupt occurs.

For most drivers of NICs that do not share an IRQ, MiniportISR seldom runs except, possibly, during driver initialization. Such a miniport sets RequestIsr to FALSE when MiniportInitialize calls this function, and such a driver has a MiniportDisableInterrupt function and, possibly, a MiniportEnableInterrupt function. The NDIS library then calls the driver’s MiniportDisableInterrupt function when an interrupt occurs on the NIC and the driver’s MiniportHandleInterrupt function does most of the I/O processing for the interrupt. Before MiniportHandleInterrupt returns control, either NDIS calls MiniportEnableInterrupt or MiniportHandleInterrupt re-enables interrupts on the NIC itself.

Whether a miniport with an ISR sets RequestIsr to TRUE when it calls this function or not, NDIS acknowledges the interrupt to the operating system so that interrupts from other devices are not blocked.

If a miniport sets RequestIsr to TRUE when it calls this function, it must dismiss the interrupt on its NIC by setting the state of the NIC so that it no longer asserts the interrupt. Interrupts can remain enabled on the NIC following the dismissal of the interrupt, or they can be disabled, depending on the design of the driver. The timing of such a dismissal depends on the InterruptMode specified when the driver calls this function, as follows:

  • For NdisInterruptLevelSensitive interrupts, MiniportISR must dismiss each interrupt as its NIC generates that interrupt. Otherwise, the interrupt is reasserted on the NIC as soon as MiniportISR returns control. If MiniportISR determines that the NIC did not generate a particular interrupt, it returns control with FALSE as soon as possible so that the ISRs for other devices on the same bus can be called promptly to dismiss the interrupt on the device that actually generated that interrupt.
  • For NdisInterruptLatched interrupts, dismissing an interrupt on the NIC is not as time-critical as it is for shared interrupts. If the miniport is designed so that each call to MiniportISR causes a subsequent call to the associated MiniportHandleInterrupt function, MiniportHandleInterrupt dismisses the interrupt on the NIC. As an alternative, such a driver can set RequestIsr to FALSE when it calls this function and supply a MiniportDisableInterrupt function, which is called instead of MiniportISR, unless MiniportHalt or MiniportInitialize is currently executing.

When a miniport supports full-duplex sends and receives, NDIS serializes calls to its MiniportISR or MiniportDisableInterrupt function for sends. NDIS separately serializes calls to its MiniportISR or MiniportDisableInterrupt function for all other operations that can cause an interrupt. Calls to the MiniportReset function are both synchronized and synchronous; NDIS prevents all other code paths in a full-duplex miniport from being entered while a device-reset operation is occurring.

If a miniport does not support full-duplex sends and receives, NDIS serializes all calls to the MiniportISR or the MiniportDisableInterrupt function for any NIC that the miniport controls. While such a driver’s MiniportISR or MiniportDisableInterrupt function is processing a particular NIC interrupt, it is not called to handle a second interrupt from the same NIC on another processor in a symmetric multiprocessor (SMP) platform.

However, the ISR or MiniportDisableInterrupt function of any driver that controls more than one device can run concurrently in SMP platforms if two of that driver’s devices happen to generate interrupts almost simultaneously and interrupts are enabled on the NIC.

If it is possible that an interrupt can occur while another driver function is accessing resources that can also be accessed from MiniportISR or MiniportDisableInterrupt, the other function must call NdisMSynchronizeWithInterrupt to have the driver-supplied MiniportSynchronizeISR function access the shared resources at DIRQL.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisMDeregisterInterrupt, NdisMInitializeTimer, NdisMPciAssignResources, NdisMSetAttributes, NdisMSetAttributesEx, NdisMSetPeriodicTimer, NdisMSynchronizeWithInterrupt, NdisOpenConfiguration, NdisReadPciSlotInformation


NdisMRegisterIoPortRange

This function sets up driver access to device I/O ports with the NdisRawReadPort XXX and NdisRawWritePort XXX functions and claims the range of I/O port addresses in the registry for that driver’s NIC.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

NDIS_STATUS NdisMRegisterIoPortRange(OUT PVOID *PortOffset,
IN NDIS_HANDLE MiniportAdapterHandle, IN UINT InitialPort,
IN UINT NumberOfPorts);

Parameters

PortOffset
Specifies a caller-supplied variable in which this function returns the mapped base virtual address for the specified bus-relative I/O port range specified by InitialPort and NumberOfPorts.
MiniportAdapterHandle
Handle input to the MiniportInitialize function.
InitialPort
Specifies the bus-relative base port address for a range of ports to be mapped.
NumberOfPorts
Specifies the number of ports in the range to be mapped.

Return Values

Returns one of the following:

NDIS_STATUS_SUCCESS
The specified range of I/O ports was mapped successfully; the value at PortOffset is valid, and the mapped range has been claimed in the registry for the NIC.
NDIS_STATUS_RESOURCE_CONFLICT
An attempt to claim the I/O port range in the registry has failed, possibly because another driver already claimed the range for its device. This function logs an error if this occurs.
NDIS_STATUS_RESOURCES
The port range could not be mapped, or NDIS could not allocate resources to check the registry for hardware-resource conflicts.
NDIS_STATUS_FAILURE
Either the bus type or bus number is out of range, or the specified InitialPort and NumberOfPorts were invalid, possibly not within the I/O port space of the current platform.

Remarks

An NIC driver calls this function from its MiniportInitialize function. MiniportInitialize must call NdisMSetAttributes or NdisMSetAttributesEx before calling this function.

This function maps a bus-relative device address range that the miniport can use subsequently to access an I/O port range on its NIC by calling the NdisRaw XXX functions. A successful call claims the specified range of I/O ports in the registry for the caller’s NIC.

Because the parameters passed to the NdisRaw XXX have been mapped, these functions run significantly faster than the corresponding NdisImmediate XXX Port XXX. After a successful call to this function, a miniport cannot call any of the NdisImmediate XXX Port XXX functions with either bus-relative addresses or mapped virtual addresses within such an I/O port range.

If its call to this function fails, MiniportInitialize releases all resources that it has already allocated for its NIC, and then fails initialization for that NIC.

Drivers of NICs with device registers in the host memory space call NdisMMapIoSpace and, subsequently, the NdisRead/WriteRegister XXX functions to access the NIC registers.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisMDeregisterIoPortRange, NdisMMapIoSpace, NdisRawReadPortBufferUchar, NdisRawReadPortBufferUlong, NdisRawReadPortBufferUshort, NdisRawReadPortUchar, NdisRawReadPortUlong, NdisRawReadPortUshort, NdisRawWritePortUchar, NdisRawWritePortUlong, NdisRawWritePortUshort


NdisMRegisterMiniport

This function registers an NIC or intermediate driver’s Miniport_* entry points and name with the NDIS library when the driver initializes.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

NDIS_STATUS NdisMRegisterMiniport(
IN NDIS_HANDLE NdisWrapperHandle,
IN PNDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics,
IN UINT CharacteristicsLength);

Parameters

NdisWrapperHandle
Handle returned by the NdisMInitializeWrapper function.
MiniportCharacteristics
Pointer to an NDIS_MINIPORT_CHARACTERISTICS structure set up by the caller.

The driver should initialize this structure with 0s before setting up any its members.

CharacteristicsLength
Specifies the length, in bytes, of the caller-supplied characteristics buffer. Depending on the value of the MajorNdisVersion member of NDIS_MINIPORT_CHARACTERISTICS, this parameter must be either sizeof(NDIS40_MINIPORT_CHARACTERISTICS) or sizeof(NDIS30_MINIPORT_CHARACTERISTICS).

If the driver includes the build instruction NDIS40_MINIPORT or NDIS30_MINIPORT, as appropriate, in its sources; if the driver writer uses the -DNDIS40_MINIPORT or ..30.. compiler switch, this parameter is set when the driver is built.

Return Values

NDIS_STATUS_SUCCESS indicates success. One of the following status values indicates failure:

NDIS_STATUS_BAD_CHARACTERISTICS
The CharacteristicsLength is too small for the MajorNdisVersion specified in the buffer at MiniportCharacteristics.
NDIS_STATUS_BAD_VERSION
The MajorNdisVersion or MinorNdisVersion specified in the characteristics structure is invalid.
NDIS_STATUS_RESOURCES
A shortage of resources, possibly memory, prevented the NDIS library from registering the caller.
NDIS_STATUS_FAILURE
This is a default error status, returned when none of the preceding errors caused the registration to fail. For example, if the NDIS library cannot load the driver’s image and lock it into system memory, it returns this error.

Remarks

An NIC driver calls this function from its DriverEntry function after DriverEntry calls the NdisMInitializeWrapper function.

Every NIC driver that exports only Miniport XXX functions must set up a characteristics structure and call this function. This structure is copied in the request to the NDIS library’s internal storage. Thus, once it has registered, a miniport driver cannot change its handler functions.

The NDIS library currently does not call MiniportReconfigure functions, so such a function in an existing miniport driver is dead code unless the miniport makes internal calls to its MiniportReconfigure function from MiniportInitialize.

After the driver has called this function, it should be prepared to be called back at the MiniportInitialize entry point specified in the characteristics structure.

NDIS intermediate drivers, which export both Miniport XXX and Protocol XXX functions, usually call the NdisIMRegisterLayeredMiniport function, instead of this function. Intermediate drivers that export only a set of Miniport XXX functions usually call this funciton.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisZeroMemory


NdisMResetComplete

This function returns the final status of a reset request for the NIC driver that previously returned NDIS_STATUS_PENDING.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMResetComplete(IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_STATUS Status, IN BOOLEAN AddressingReset);

Parameters

MiniportAdapterHandle
Handle originally input to the MiniportInitialize function.
Status
Specifies the final status of the reset operation just completed
AddressingReset
Specifies TRUE if the reset affected the miniport’s network address information so that it needs to be reloaded.

Remarks

If the MiniportReset function returns NDIS_STATUS_PENDING, the miniport must call this function when it completes the reset operation. This call causes NDIS to forward the completion-status information to the protocol driver, if any, that called NdisReset to initiate the call to MiniportReset.

The NDIS library can also call the MiniportReset function, independently of any reset requests from protocol drivers bound to a particular NIC, when NDIS determines that a sent packet or a request that it submitted to the miniport has timed out.

Some NICs lose all multicast address, packet filter, or functional address information when a soft reset is issued. The driver of such an NIC sets AddressingReset to TRUE when it calls this function, causing NDIS to call its MiniportSetInformation function to restore the addressing state.

An NDIS intermediate driver either sets AddressingReset to TRUE when it calls this function or restores its own addressing information, such as medium-specific functional, multicast, and/or group addresses.

A driver that calls this function runs at IRQL DISPATCH_LEVEL.

See Also

NdisReset


NdisMSendComplete

This function returns the packet and final status of a completed send request for which the driver previously returned NDIS_STATUS_PENDING.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMSendComplete(IN NDIS_HANDLE MiniportAdapterHandle,
IN PNDIS_PACKET Packet, IN NDIS_STATUS Status);

Parameters

MiniportAdapterHandle
Handle originally input to the MiniportInitialize function.
Packet
Pointer to the protocol-allocated packet originally input to the MiniportSend function.
Status
Specifies the final status of the transmit request that has just been completed.

Remarks

The NDIS library queues incoming send packets on behalf of miniports so that each NIC driver can deal with one device-transmit operation at a time, although a miniport can transmit several packets per operation, depending on the capabilities of its NIC. NDIS serializes the submission of incoming packet arrays to each miniport’s MiniportSendPackets function, and it serializes the submission of packets to each miniport’s MiniportSend function. NDIS queues incoming send requests in first-in, first-out (FIFO) order when it cannot pass on each such request immediately because the underlying NIC driver is already busy.

If MiniportSendPackets sets the Status in the out-of-band data block for a packet to NDIS_STATUS_PENDING or if MiniportSend returns NDIS_STATUS_PENDING for an incoming packet, the miniport must eventually call this function with the original packet to indicate which send request it has completed. While the status of such a send packet is pending, the miniport retains ownership of that packet.

A call to this function causes NDIS to call the ProtocolSendComplete function of the driver that initiated the request with its call to NdisSend. The miniport’s call to this function releases ownership of the specified packet to the protocol driver that originally allocated it.

If MiniportSend returns a status other than NDIS_STATUS_PENDING for a specified packet, the miniport never calls this function with that packet. The return from MiniportSend releases ownership of such a packet.

Consequently, a miniport must not call this function with any packet for which its MiniportSend function did not return NDIS_STATUS_PENDING. Any send packet for which an NIC driver returns something other than NDIS_STATUS_PENDING should be considered inaccessible by that miniport as soon as its MiniportSend function returns control.

A miniport’s call to this function does not necessarily mean that a particular packet has been transmitted over the wire. Usually, such a packet has been transmitted except, possibly, by the driver of an NIC in which packets can be queued in the hardware.

Miniport drivers that declared their devices of type NdisMediumWan in response to a preceding OID_GEN_MEDIA_SUPPORTED or OID_GEN_MEDIA_IN_USE request call NdisMWanSendComplete, rather than this function.

A driver that calls this function runs at IRQL DISPATCH_LEVEL.

See Also

NdisMSendResourcesAvailable, NdisSend


NdisMSendResourcesAvailable

This function notifies NDIS that a miniport has sufficient internal resources to accept another send request, even though one or more outstanding send packets are pending within the miniport.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMSendResourcesAvailable(
IN NDIS_HANDLE MiniportAdapterHandle);

Parameters

MiniportAdapterHandle
Handle originally input to the MiniportInitialize function.

Remarks

The NDIS library queues send requests on behalf of miniports so that each NIC driver can deal with one device transmit operation at a time, although a miniport can transmit several packets per operation, depending on the capabilities of its NIC. NDIS serializes the submission of incoming packet arrays to each miniport’s MiniportSendPackets function, and it serializes the submission of packets to each miniport’s MiniportSend function. NDIS queues incoming send requests in first-in, first-out (FIFO) order.

Any miniport retains ownership of such a send packet in one of the following ways:

  • Its MiniportSendPackets function sets the Status member in the out-of-band data block for a packet to NDIS_STATUS_PENDING with NDIS_SET_PACKET_STATUS.
  • Its MiniportSend function returns NDIS_STATUS_PENDING.

In either of these circumstances, the NIC driver eventually must call NdisMSendComplete or NdisMWanSendComplete to indicate that it has released ownership of the packet and that the driver has sufficient resources available to accept the next transmit request.

However, before a miniport calls NdisMSendComplete for a pending packet, it can call this function if the driver and its NIC are capable of accepting another send request immediately, assuming NDIS has one in its queue to submit to that driver. Such a call allows the driver of a high-capacity NIC to optimize transmissions over the network by sending more data at a time.

This function can be called only in the time between the return of NDIS_STATUS_PENDING for a given packet and the miniport’s call to NdisMSendComplete with that packet.

If a miniport returns any value except NDIS_STATUS_PENDING for a particular packet from MiniportSendPackets or from MiniportSend, it should call neither this function nor NdisMSendComplete. Any send packet for which an NIC driver returns something other than NDIS_STATUS_PENDING should be considered inaccessible by that miniport on return from its MiniportSendPackets or MiniportSend function.

A WAN miniport cannot call this function.

A driver that calls this function runs at IRQL DISPATCH_LEVEL.

See Also

NdisMSendComplete, NdisSend


NdisMSetAttributes

This function informs the NDIS library about significant features of the caller’s NIC during initialization.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMSetAttributes(IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_HANDLE MiniportAdapterContext, IN BOOLEAN BusMaster,
IN NDIS_INTERFACE_TYPE AdapterType);

Parameters

MiniportAdapterHandle
Handle input to the MiniportInitialize function.
MiniportAdapterContext
Handle to a resident context area allocated by MiniportInitialize.
BusMaster
Specifies TRUE if the caller’s NIC is a busmaster DMA device.
AdapterType
Specifies the I/O bus interface type of the caller’s NIC, which usually is the type of I/O bus on which the NIC is connected, as one of the following:
NdisInterfaceInternal
Specifies a host-specific internal interface.
NdisInterfaceIsa
Specifies the ISA interface.
NdisInterfaceEisa
Specifies the extended ISA (EISA) interface.
NdisInterfacePci
Specifies the Peripheral Component Interconnect (PCI) interface.
NdisInterfacePcMcia
Specifies the Personal Computer Memory Card International Association (PCMCIA) interface.

Remarks

A MiniportInitialize function must call this function or NdisMSetAttributesEx before calling any other NdisMRegister XXX or Ndis XXX function that depends on the information supplied to this function or NdisMSetAttributesEx. For example, a call to the NdisMAllocateMapRegisters function fails if MiniportInitialize has not yet called this function with BusMaster set to TRUE or NdisMSetAttributesEx with NDIS_ATTRIBUTE_BUS_MASTER set in the AttributeFlags.

In general, an NIC driver must call this function or NdisMSetAttributesEx before it calls any Ndis XXX function that claims hardware resources in the registry for its NIC because NDIS must have the BusMaster or AttributeFlags value, respectively, before such a call is made and because the driver usually needs the memory at MiniportAdapterContext to store information for these calls. This restriction implies that an NIC driver’s MiniportInitialize function cannot call the following Ndis XXX functions before it calls this function or NdisMSetAttributesEx:

  • NdisMPciAssignResources
  • NdisMAllocateMapRegisters and NdisMAllocateSharedMemory
  • NdisMMapIoSpace
  • NdisMRegisterDmaChannel
  • NdisMRegisterInterrupt
  • NdisMRegisterIoPortRange and, consequently, the NdisRaw XXX Port XXX functions

However, before calling this function or NdisMSetAttributesEx, an NIC driver can call the NDIS configuration functions to retrieve configuration information installed in the registry and the NdisImmediate XXX, such as NdisImmediateReadPciSlotInformation or NdisImmediateReadSharedMemory, as well as the NdisImmediate XXX Port XXX functions. MiniportInitialize can also call the bus-type-specific NdisRead XXX functions, such as NdisReadPciSlotInformation, as long as the installed registry entry for the driver’s interface type matches the bus-type-specific NdisRead XXX MiniportInitialize calls.

The MiniportAdapterContext handle supplied to this function or NdisMSetAttributesEx becomes an input parameter to all Miniport XXX functions that were registered, along with MiniportInitialize, in the call to NdisMRegisterMiniport. Usually, this handle is a pointer to resident memory, allocated by MiniportInitialize, in which the driver maintains NIC-specific run-time state.

Intermediate drivers must call NdisMSetAttributesEx, rather than this function. NIC drivers can call either of these functions, but NdisMSetAttributesEx allows a miniport to adjust the intervals at which its MiniportCheckForHang and MiniportReset functions are called.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisMMapIoSpace, NdisMPciAssignResources, NdisMRegisterInterrupt, NdisMRegisterIoPortRange, NdisMRegisterMiniport, NdisMSetAttributesEx, NdisOpenConfiguration, NdisReadPciSlotInformation, NdisWritePciSlotInformation


NdisMSetAttributesEx

This function informs the NDIS library about significant features of the caller’s NIC or virtual NIC during initialization.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMSetAttributesEx(IN NDIS_HANDLE MiniportAdapterHandle, IN NDIS_HANDLE MiniportAdapterContext,
IN UINT CheckForHangTimeInSeconds,
OPTIONAL, IN ULONG AttributeFlags,
IN NDIS_INTERFACE_TYPE AdapterType);

Parameters

MiniportAdapterHandle
Handle input to the MiniportInitialize function.
MiniportAdapterContext
Handle to a resident context area allocated by MiniportInitialize.
CheckForHangTimeInSeconds
Specifies the interval, in seconds, at which NDIS should call the MiniportCheckForHang function, if any. Specifying 0 for this parameter indicates that NDIS should call MiniportCheckForHang at NDIS’s default two-second interval and that NDIS should call the MiniportReset function at the default four-second time-out interval for pending sends and requests that NDIS subsequently holds queued to the caller.

Specifying a value greater than 2 extends both the check-for-hang and time-out intervals. NDIS uses double the specified check-for-hang interval as its time-out interval for the caller.

AttributeFlags
Specifies a bitmask that can be set with one or more of the following flags:
NDIS_ATTRIBUTE_BUS_MASTER
Set if the caller’s NIC is a busmaster DMA device.
NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT
Set if NDIS should not attempt to time-out pending send packets that it holds queued to the caller. Intermediate drivers should set this flag, but NIC drivers should not.
NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT
Set if NDIS should not attempt to time-out pending query and set requests that it holds queued to the caller. Intermediate drivers should set this flag, but NIC drivers should not.
NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER
Set if the caller is an intermediate driver.
NDIS_ATTRIBUTE_IGNORE_TOKEN_RING_ERRORS
Set if NDIS should not call a token ring NIC driver’s MiniportReset function if token ring errors are indicated.
AdapterType
Specifies the I/O bus interface type of the caller’s NIC, which usually is the type of I/O bus on which the NIC is connected, as one of the following:
NdisInterfaceInternal
Specifies a host-specific internal interface.
NdisInterfaceIsa
Specifies the ISA interface.
NdisInterfaceEisa
Specifies the extended ISA (EISA) interface.
NdisInterfacePci
Specifies the Peripheral Component Interconnect (PCI) interface.
NdisInterfacePcMcia
Specifies the Personal Computer Memory Card International Association (PCMCIA) interface.

This parameter is irrelevant for intermediate drivers, which should pass 0 for this parameter to this function.

Remarks

MiniportInitialize must call this function or NdisMSetAttributes before calling any other NdisMRegister XXX or Ndis XXX function that depends on the information supplied to this function. For example, an NIC driver’s call to NdisMAllocateMapRegisters fails if MiniportInitialize has not yet called this function with the AttributeFlags set with NDIS_ATTRIBUTE_BUS_MASTER.

Intermediate drivers must call this function, rather than NdisMSetAttributes, and they must set the NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER in the AttributeFlags. Setting this flag causes NDIS to treat an intermediate driver as a full-duplex miniport, which prevents rare but intermittent deadlocks from occurring in the intermediate driver. Consequently, every intermediate driver must be capable of handling concurrent sends and indications.

NIC drivers can call either of these functions from MiniportInitialize, but NdisMSetAttributes does not allow its caller to adjust the interval at which an NIC driver’s MiniportCheckForHang and/or MiniportReset function(s) are called.

The value of CheckForHangTimeInSeconds determines the NDIS library’s time-out interval on sends and requests that it holds queued to the caller. By default, NDIS times out queued sends and requests at twice the check-for-hang interval, after which it calls the MiniportReset function, unless the driver sets AttributeFlags with NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT and NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT when it calls this function. Intermediate drivers should set these flags when calling this function because such a driver cannot determine or control when the underlying device driver processes sends and requests.

NIC drivers should not set the NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT and NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT flags, although NDIS honors such a specification by an NIC driver. However, NIC drivers can adjust the time-out interval at which their MiniportReset functions are called by specifying an explicit CheckForHangTimeInSeconds. For example, an NIC driver that emulates Ethernet over a modem might not complete every packet within the default time-out interval of the NDIS library. Whenever a packet appears to time out on such an NIC, NDIS assumes that the NIC is no longer operating correctly and calls the driver’s MiniportReset function. For the driver of such an NIC, calling this function with a CheckForHangTimeInSeconds set to something greater than 2 both prevents unnecessary resets and extends the interval at which its MiniportCheckForHang function, if any, is called to test the operational state of the NIC.

In general, an NIC driver must call this function before it calls any Ndis XXX function that claims hardware resources in the registry for its NIC, because NDIS must have the AttributeFlags value before such a call is made and because the driver usually needs the memory at MiniportAdapterContext to store information for these calls. This restriction implies that an NIC driver’s MiniportInitialize function cannot call the following Ndis XXX functions before it calls this function:

  • NdisMPciAssignResources
  • NdisMAllocateMapRegisters and NdisMAllocateSharedMemory
  • NdisMMapIoSpace
  • NdisMRegisterDmaChannel
  • NdisMRegisterInterrupt
  • NdisMRegisterIoPortRange and, consequently, the NdisRaw XXX Port XXX functions

However, before calling this function, any driver’s MiniportInitialize function can call the NDIS configuration functions to retrieve configuration information installed in the registry. Before calling this function, an NIC driver can call the NdisImmediate XXX, such as NdisImmediateReadPciSlotInformation or NdisImmediateReadSharedMemory, as well as the NdisImmediate XXX Port XXX functions. MiniportInitialize can also call the bus-type-specific NdisRead XXX functions, such as NdisReadPciSlotInformation, as long as the installed registry entry for the driver’s interface type matches the bus-type-specific NdisRead XXX MiniportInitialize calls.

The MiniportAdapterContext handle supplied to this function becomes an input parameter to all Miniport XXX functions that were registered, along with MiniportInitialize, in the call to NdisMRegisterMiniport or NdisIMRegisterLayeredMiniport. Usually, this handle is a pointer to resident memory allocated by MiniportInitialize, in which the driver maintains NIC-specific run-time state.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisAllocateMemory, NdisMMapIoSpace, NdisMPciAssignResources, NdisMRegisterInterrupt, NdisMRegisterIoPortRange, NdisMRegisterMiniport, NdisOpenConfiguration


NdisMSetInformationComplete

This function returns the final status of a completed set-information request for which the driver previously returned NDIS_STATUS_PENDING.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMSetInformationComplete(
IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_STATUS Status);

Parameters

MiniportAdapterHandle
Handle originally input to the MiniportInitialize function.
Status
Specifies the final status of the immediately preceding request input to MiniportSetInformation.

Remarks

A miniport calls this function after it has carried out the operation originally requested of its MiniportSetInformation function. This call releases the miniport’s ownership of all buffer addresses that were passed to MiniportSetInformation.

This function causes NDIS to return the original request to the ProtocolRequestComplete function of the driver, if any, that initiated the set-information operation when it called NdisRequest. The NDIS library can also call MiniportSetInformation directly with NDIS-initiated set-information requests, particularly during initialization just after MiniportQueryInformation returns control.

All calls to a driver’s MiniportSetInformation function are both synchronous and serialized. That is, NDIS never submits another such request until the miniport has completed the preceding request.

A driver that calls this function runs at IRQL DISPATCH_LEVEL.

See Also

NdisRequest


NdisMSetPeriodicTimer

This function sets a timer to fire periodically, thus running an associated MiniportTimer function repeatedly at fixed intervals.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMSetPeriodicTimer(IN PNDIS_MINIPORT_TIMER Timer,
IN UINT MillisecondsPeriod);

Parameters

Timer
Pointer to caller-supplied resident storage for a timer object previously initialized with the NdisMInitializeTimer function.
MillisecondsPeriod
Specifies the interval, in milliseconds, to time out before calling the MiniportTimer function unless the timer is canceled or this interval is reset.

Remarks

This function causes the driver-supplied MiniportTimer function, which was associated with the timer object when MiniportInitialize called NdisMInitializeTimer, to be run repeatedly whenever the given MillisecondsPeriod expires. At the initial call to this function, the timer object is queued until the MillisecondsPeriod expires; then the MiniportTimer function is run, and the timer object is automatically requeued for the next interval.

By contrast, NdisMSetTimer causes the driver-supplied function associated with a particular timer object to run only once after the given MillisecondsToDelay expires. That is, execution of this function associated with the Timer passed to NdisMSetTimer is episodic, rather than periodic.

As a general rule, a miniport should allocate and initialize two timer objects if it calls both this function and NdisMSetTimer. Such a driver is likely to have two MiniportTimer functions with different functionality, each associated with a particular timer object when it is initialized with NdisMInitializeTimer. For example, a MiniportTimer function that runs periodically might poll device state at regular intervals, whereas another MiniportTimer function might retry a particular run-time operation only if it times out on the NIC.

If a miniport calls this function, NdisMCancelTimer, or NdisMSetTimer with the same Timer pointer originally passed to this function, the current call cancels its preceding call to this function, possibly resetting the MillisecondsPeriod specified originally. Any call to an NDIS timer function resets the specified timer to expire at the interval specified in the most recent call and causes the associated MiniportTimer function to run when the most recently specified interval has expired.

Timer resolution on the host varies. Consequently, calling this function with very small periods does not necessarily cause the execution of the MiniportTimer function exactly when the specified interval expires.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

See Also

NdisMCancelTimer, NdisMInitializeTimer, NdisMSetTimer


NdisMSetTimer

This function sets a timer to fire after a specified interval, thus running an associated MiniportTimer function when the timer fires.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMSetTimer(IN PNDIS_MINIPORT_TIMER Timer,
IN UINT MillisecondsToDelay);

Parameters

Timer
Pointer to caller-supplied resident storage for a timer object previously initialized with the NdisMInitializeTimer function.
MillisecondsToDelay
Specifies the interval, in milliseconds, to time out before calling the MiniportTimer function.

Remarks

This function causes the driver-supplied MiniportTimer function, which was associated with the timer object when MiniportInitialize called NdisMInitializeTimer, to run once after the given MillisecondsToDelay expires. Execution of the MiniportTimer function associated with the Timer passed to this function is episodic, rather than periodic. A miniport must call this function each time the associated timer function should be run.

By contrast, the NdisMSetPeriodicTimer function causes the associated MiniportTimer function to be run repeatedly whenever the specified MillisecondsPeriod expires. At the initial call to NdisMSetPeriodicTimer, the timer object is queued until the MillisecondsPeriod expires; then the MiniportTimer function is run, and the timer object is automatically requeued for the next interval.

Generally, a miniport should allocate and initialize two timer objects if it calls both NdisMSetPeriodicTimer and this function. Such a driver is likely to have two MiniportTimer functions with different functionality, each associated with a particular timer object when it is initialized with NdisMInitializeTimer. For example, a MiniportTimer function that runs periodically might poll device state at regular intervals, whereas another MiniportTimer function might retry a particular run-time operation only if it times out on the NIC.

If a miniport calls this function, NdisMCancelTimer, or NdisMSetPeriodicTimer with the same Timer pointer originally passed to this function before the originally specified MillisecondsToDelay expires, the current call cancels its preceding call to this function. Any call to an NDIS timer function resets the specified timer to expire at the interval specified in the most recent call and causes the associated MiniportTimer function to run when the most recently specified interval has expired.

Timer resolution on the host varies. Consequently, calling this function with very small time-out values does not necessarily cause the execution of MiniportTimer exactly when the specified interval expires.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

See Also

NdisMCancelTimer, NdisMInitializeTimer, NdisMSetPeriodicTimer


NdisMSleep

This function delays execution of the caller for a specified interval, in microseconds.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMSleep(IN ULONG MicrosecondsToSleep);

Parameters

MicrosecondsToSleep
Specifies the number of microseconds to delay.

Remarks

For the specified MicrosecondsToSleep, the caller’s thread of execution is put into a wait state, thus allowing other threads to get work done on the current processor. When the specified interval expires, the caller of this function resumes execution.

An NDIS driver should always call this function in preference to the NdisStallExecution function unless the driver is running at IRQL >= DISPATCH_LEVEL. This function can accept a larger delay interval than NdisStallExecution, which should never be called with an interval greater than 50 microseconds.

NIC drivers can call this function from their MiniportInitialize and, possibly, MiniportHalt functions when either function must wait for state changes to occur in the NIC before that function continues its operations.

Both this function and NdisStallExecution allow an NIC driver to specify a delay consistently and independently of the clock speed of the host CPU. Neither function involves a timer object used by the NdisSetTimer or the NdisSetPeriodicTimer function. The resolution of the host system clock varies, so very short delays can take slightly longer than the caller of this function or NdisStallExecution specified.

A driver that calls this function runs at IRQL < DISPATCH_LEVEL.

See Also

NdisMSetTimer, NdisMSetPeriodicTimer, NdisStallExecution


NdisMSynchronizeWithInterrupt

This function synchronizes execution of a Miniport-supplied function with the MiniportISR or the MiniportDisableInterrupt function.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

BOOLEAN NdisMSynchronizeWithInterrupt(
IN PNDIS_MINIPORT_INTERRUPT Interrupt,
IN PVOID SynchronizeFunction, IN PVOID SynchronizeContext);

Parameters

Interrupt
Pointer to the caller-supplied storage for the interrupt object initialized with the NdisMRegisterInterrupt function.
SynchronizeFunction
Specifies the entry point of the driver’s MiniportSynchronizeISR function.
SynchronizeContext
Pointer to a miniport-determined context area to be passed to the MiniportSynchronizeISR function when it is called.

Return Values

Returns the Boolean value returned by MiniportSynchronizeISR.

Remarks

The value returned by MiniportSynchronizeISR is also returned by this function. This propagated value can be used to provide a status to the caller.

Any miniport function that shares resources with any other driver function that runs at DIRQL must use this function to synchronize its access to those resources. The MiniportSynchronizeISR function also runs at DIRQL, and the shared resources are protected by a system-allocated spin lock on multiprocessor platforms. Thus, the shared resources are protected from simultaneous access by MiniportISR or MiniportDisableInterrupt and the caller whenever the driver is running on a multiprocessor platform.

This function releases the system spin lock and restores the original IRQL of its caller before it returns control.

A driver that calls this function runs at IRQL <= DIRQL.

See Also

NdisMDeregisterInterrupt, NdisMRegisterInterrupt


NdisMTransferDataComplete

This function returns the packet and completion status for a transfer-data request for which the miniport previously returned NDIS_STATUS_PENDING.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMTransferDataComplete(IN NDIS_HANDLE MiniportAdapterHandle, IN PNDIS_PACKET Packet,
IN NDIS_STATUS Status, IN UINT BytesTransferred);

Parameters

MiniportAdapterHandle
Handle originally input to the MiniportInitialize function.
Packet
Pointer to the protocol-allocated packet for which the MiniportTransferData function previously returned NDIS_STATUS_PENDING.
Status
Specifies the final NDIS_STATUS_XXX for the just-completed transfer-data request.
BytesTransferred
Specifies the number of bytes actually transferred to the packet.

Remarks

Whenever MiniportTransferData returns NDIS_STATUS_PENDING for a specified packet, the driver must call this function when it has finished copying the requested data into that packet or must fail the request.

A miniport that indicates receives with NdisMIndicateReceivePacket never calls this function because such a driver always indicates full packets up to higher-level drivers.

Miniports that report their NIC’s media type as NdisMediumArcnet878_2 do not call this function either. NDIS copies all packet data that such a driver indicates.

A driver that calls this function runs at IRQL DISPATCH_LEVEL.

See Also

NdisAllocatePacket, NdisMIndicateReceivePacket, NdisTransferData


NdisMUnmapIoSpace

This function releases a virtual range mapped by an initialization-time call to the NdisMMapIoSpace function.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMUnmapIoSpace(IN NDIS_HANDLE MiniportAdapterHandle,
IN PVOID VirtualAddress, IN UINT Length);

Parameters

MiniportAdapterHandle
Handle originally input to the MiniportInitialize function.
VirtualAddress
Specifies the base virtual address for the mapped range that was returned by the NdisMMapIoSpace function.
Length
Specifies the number of bytes in the range that was mapped with NdisMMapIoSpace.

Remarks

When a miniport is unloading, any memory range that it mapped during initialization with NdisMMapIoSpace must be released with a call to this function.

The Length passed to this function must match the Length originally passed to NdisMMapIoSpace.

This function can be called only from an NIC driver’s MiniportInitialize and MiniportHalt functions.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisMMapIoSpace


NdisMUpdateSharedMemory

This function ensures that data that has just transferred from a busmaster network card and that is about to be read from driver-allocated shared memory is current.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisMUpdateSharedMemory(
IN NDIS_HANDLE MiniportAdapterHandle, IN ULONG Length,
IN PVOID VirtualAddress, IN NDIS_PHYSICAL_ADDRESS PhysicalAddress);

Parameters

MiniportAdapterHandle
Handle originally input to the MiniportInitialize function.
Length
Specifies the number of bytes in the range.
VirtualAddress
Specifies the base virtual address within a range returned by the NdisMAllocateSharedMemory or the NdisMAllocateSharedMemoryAsync function.
PhysicalAddress
Specifies the physical address mapped to VirtualAddress.

Remarks

Windows CE does not support direct memory access (DMA) at this time. The Windows CE version of this function is a stub that does no work. When Windows CE does support DMA, this function will be more fully implemented.


NdisOpenAdapter

This function sets up a binding between the calling protocol and a particular underlying NIC driver or NDIS intermediate driver.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisOpenAdapter(OUT PNDIS_STATUS Status,
OUT PNDIS_STATUS OpenErrorStatus,
OUT PNDIS_HANDLE NdisBindingHandle,
OUT PUINT SelectedMediumIndex, IN PNDIS_MEDIUM MediumArray,
IN UINT MediumArraySize, IN NDIS_HANDLE NdisProtocolHandle,
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_STRING AdapterName, IN UINT OpenOptions,
IN PSTRING AddressingInformation);

Parameters

Status
Pointer to a caller-supplied variable that can be one of the following values on return from this function:
STATUS_SUCCESS
The requested binding is now set up, so the caller can use the values returned at NdisBindingHandle and SelectedMediumIndex in subsequent calls to the Ndis XXX functions.
NDIS_STATUS_PENDING
The requested operation is being handled asynchronously, and the caller’s ProtocolOpenAdapterComplete function will be called when the open is completed.
NDIS_STATUS_RESOURCES
The requested operation failed because NDIS could not allocate sufficient memory or initialize the state that it uses to track an open binding.
NDIS_STATUS_ADAPTER_NOT_FOUND
The requested operation failed because the name at AdapterName could not be found in the system object namespace.
NDIS_STATUS_UNSUPPORTED_MEDIA
The array at MediumArray did not specify any medium that is supported by NDIS or by the underlying driver.
NDIS_STATUS_CLOSING
Either the caller or the physical or virtual device designated at AdapterName is being closed.
NDIS_STATUS_OPEN_FAILED
The open attempt failed for none of the preceding specific reasons. For example, possibly, NDIS could not initialize the filter package for the selected medium.
OpenErrorStatus
Pointer to a caller-supplied variable that can contain an NDIS_STATUS_XXX error supplying more information if this function returns an error at Status. For example, the driver of a token ring NIC might return a ring error in this variable.
NdisBindingHandle
Pointer to a caller-supplied variable in which NDIS returns a handle representing a successful binding between the caller and the specified physical or virtual NIC specified at AdapterName.
SelectedMediumIndex
Pointer to a caller-supplied variable in which NDIS returns the index of the array element that specifies the type of media that the underlying NDIS driver uses.
MediumArray
Pointer to an array of NDIS_MEDIUM-type values specifying the types of media that the caller supports. Possible elements include any proper subset of the following:
NdisMedium802_3
Specifies an Ethernet (802.3) network.
NdisMedium802_5
Specifies a Token Ring (802.5) network.
NdisMediumFddi
Specifies a Fiber Distributed Data Interface (FDDI) network.
NdisMediumWan
Specifies a wide area network. This type covers various forms of point-to-point and WAN NICs, as well as variant address and header formats that must be negotiated between the protocol driver and the underlying driver after the binding is established.
NdisMediumLocalTalk
Specifies a LocalTalk network.
NdisMediumDix
Specifies an Ethernet network for which the drivers use the DIX Ethernet header format.
NdisMediumArcnetRaw
Specifies an ARCNET network.
NdisMediumArcnet878_2
Specifies an ARCNET (878.2) network.
NdisMediumAtm
This value is reserved for future use. Currently, NIC drivers support ATM through LAN emulation, LanE 1.0 as defined in the ATM Forum’s 1.0 specification and UNI 3.1 signaling. Such a driver should report its medium type as either of NdisMedium802_3 or NdisMedium802_5.
NdisMediumWirelessWan
Specifies a wireless network. This type covers various wireless media that do not include the infrared wireless types designated by NdisMediumIrda.
NdisMediumIrda
This value is reserved for future use.
MediumArraySize
Specifies the number of elements at MediumArray.
NdisProtocolHandle
Handle returned by NdisRegisterProtocol.
ProtocolBindingContext
Handle to a caller-supplied resident context area in which the protocol maintains state information about this binding after it has been established.
AdapterName
Pointer to a counted string, specified in the system-default character set, naming the NIC or the virtual adapter of an underlying NDIS driver that exports a set of upper-edge (Miniport XXX) functions.
OpenOptions
Specifies a bitmask containing flags that the caller passes to the next-lower driver, assumed to be an NIC driver. Currently, this parameter is reserved for system use.
AddressingInformation
Pointer to an optional variable-length counted string containing information specific to the underlying NIC that the NIC driver can use to program the netcard. This pointer can be NULL.

If it is supplied, the addressing information must remain valid until the open operation completes. An underlying NIC driver that supports an asynchronous modem can use this information for dialing.

Remarks

Protocol drivers call this function from either their DriverEntry or their ProtocolBindAdapter functions. NDIS intermediate drivers usually make this call from their ProtocolBindAdapter functions.

The string at AdapterName remains valid only until this function returns control, even if it returns NDIS_STATUS_PENDING at Status.

The variables at NdisBindingHandle and SelectedMediumIndex should be ignored until the ProtocolOpenAdapterComplete function is called if this function returns NDIS_STATUS_PENDING. Because these variables can remain invalid until ProtocolOpenAdapterComplete is called, they cannot be on the stack. Usually, these variables reside in the ProtocolBindingContext area since this handle is an input parameter to ProtocolOpenAdapterComplete.

A protocol driver should keep the handle returned at NdisProtocolHandle. It is a required parameter to other NDIS functions that the driver calls subsequently. The supplied ProtocolBindingContext is an input parameter to the caller’s protocol functions.

The caller uses the value returned at SelectedMediumIndex in subsequent calls to the NdisRequest function. The OIDs that it sets in the request packet depend on the returned NdisMedium XXX function. For example, if NdisMediumWan is returned at SelectedMediumIndex, the protocol driver calls NdisRequest specifying OID_WAN_MEDIUM_SUBTYPE in a query to determine which of the WAN media types that the underlying driver uses.

If a previously issued global query of OID_NETWORK_TYPE for wireless media indicates that the driver and underlying NIC support more than one NdisMediumWirelessWan-type medium, the protocol must select one of the supported media as soon as NDIS has set up the binding and before the protocol selects the header format.

As another example, if NdisMedium802_3 is returned, a protocol driver can determine whether the underlying driver supports packet priority by calling NdisRequest, specifying OID_802_3_MAC_OPTIONS as a query to check whether the underlying driver sets the flags with NDIS_802_3_MAC_OPTION_PRIORITY. If this flag is set when the query is complete, the protocol driver can pass down prioritized packets to the underlying NIC driver with the NdisSendPackets function. The protocol driver can expect its ProtocolReceivePacket function to get indications of prioritized packets if the underlying driver also supports multipacket receive indications.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisCloseAdapter, NdisMIndicateReceivePacket, NdisRegisterProtocol, NdisRequest


NdisOpenConfiguration

This function returns a handle for an NDIS NIC driver’s \DriverName\Parms registry key.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisOpenConfiguration(OUT PNDIS_STATUS Status,
OUT PNDIS_HANDLE ConfigurationHandle,
IN NDIS_HANDLE WrapperConfigurationContext);

Parameters

Status
Pointer to a caller-supplied variable in which this function returns the status of its attempt to open the registry key. Possible return values are the following:
NDIS_STATUS_SUCCESS
The value at ConfigurationHandle is valid.
NDIS_STATUS_FAILURE
The key could not be opened.
ConfigurationHandle
Pointer to a caller-supplied variable in which this function returns a handle to the registry HKEY_LOCAL_MACHINE\System\CurrentControlSet
\Services\DriverName\Parameters key. Value entries under this key are provided by the driver’s installation script.
WrapperConfigurationContext
Handle input to the MiniportInitialize function.

Remarks

With the handle returned by this function, an NDIS miniport can call the NdisReadConfiguration function one or more times to extract configuration information about its NIC from the registry. A miniport can also call NdisReadNetworkAddress with this handle to retrieve software-configurable network address information that was stored in the registry when its NIC was installed in the current computer.

A miniport’s installation script must store at least the following configuration information in the registry:

  • The NIC’s I/O bus interface type.
  • If it is not on an ISA bus, the bus number.
  • The NIC’s adapter ID value, which, depending on the I/O bus interface type, is equivalent to one of following bus-type-specific configuration data values:
    • If the NIC is on a PCI bus, the value of the PCI DeviceId

Drivers of NICs on ISA buses usually get bus-relative configuration parameters for an NIC from the registry with the NdisReadConfiguration function. Drivers of NICs on other types of I/O buses can also call Ndis XXX bus-type-specific configuration functions to get bus-relative NIC-specific configuration parameters suitable for calling functions, such as NdisMRegisterInterrupt, NdisMMapIoSpace, and/or NdisMRegisterIoPortRange.

An NIC driver calls the NdisMSetAttributes or the NdisMSetAttributesEx function to identify the type of I/O bus on which its NIC is likely to be found before that driver calls any of the bus-type-specific configuration functions.

After a driver has consumed and, possibly, modified the registry configuration information, the driver must call the NdisCloseConfiguration function to release the handle obtained from this function and to free any temporary storage that NDIS allocated in the driver’s calls to NdisReadConfiguration, NdisReadNetworkAddress, and/or NdisWriteConfiguration.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisMMapIoSpace, NdisMRegisterInterrupt, NdisMRegisterIoPortRange, NdisMRegisterMiniport, NdisMSetAttributes, NdisMSetAttributesEx, NdisOpenProtocolConfiguration, NdisReadNetworkAddress, NdisReadPciSlotInformation, NdisRegisterProtocol, NdisWriteConfiguration


NdisOpenProtocolConfiguration

This function returns a handle for the HKEY_LOCAL_MACHINE\Comm\ProtocolName\Parms registry key.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisOpenProtocolConfiguration(OUT PNDIS_STATUS Status,
OUT PNDIS_HANDLE ConfigurationHandle,
IN PNDIS_STRING ProtocolSection);

Parameters

Status
Pointer to a caller-supplied variable that is set to NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE on return from this function.
ConfigurationHandle
Pointer to a caller-supplied variable in which this function returns the handle to the registry key for the named driver to which the caller will bind itself later. Value entries under this key contain protocol-installed, adapter-specific information.
ProtocolSection
Pointer to a counted string, specified in the system-default character set, naming the NDIS driver, effectively the adapter, for which the Parameters\ProtocolName key in the registry protocol section should be opened.

For NDIS drivers that have a ProtocolBindAdapter function, this pointer is the SystemSpecific1 input parameter to that function.

Remarks

Currently, the Windows CE version of this function is a stub that exists to make existing code compile without error; it does no actual work. Current protocol stack implementations for Windows CE have their own means for obtaining configuration information. If that changes in later releases of Windows CE, this function may be developed more fully.


NdisPrintString

This function displays a specified string on the debugging window.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

ULONG NdisPrintString(PNDIS_STRING String);

Parameters

String
Pointer to a counted string in the system default character set.

Return Values

Returns the number of characters written to the debugging window.

Remarks

This function supplies the equivalent of printf debugging support.

See Also

NdisInitAnsiString, NdisInitializeString, NdisInitUnicodeString


NdisQueryBuffer

This function retrieves the size of the range from a buffer descriptor and, optionally, its base virtual address.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisQueryBuffer(IN PNDIS_BUFFER Buffer,
OUT PVOID *VirtualAddress OPTIONAL, OUT PUINT Length);

Parameters

Buffer
Pointer to the buffer descriptor.
VirtualAddress
Pointer to a caller-supplied variable in which this function returns the base virtual address of the range described.
Length
Pointer to to a caller-supplied variable in which this function returns the number of bytes in the virtual range.

Remarks

NDIS drivers use this function to retrieve information from the buffer descriptors chained to incoming packets for subsequent transfer operations.

The driver must release any spin lock it is holding before calling this function.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

See Also

NdisGetFirstBufferFromPacket, NdisMoveFromMappedMemory, NdisMoveMemory, NdisMoveToMappedMemory, NdisQueryBufferOffset, NdisQueryPacket, NdisRawReadPortBufferUchar, NdisRawReadPortBufferUlong, NdisRawReadPortBufferUshort, NdisRawWritePortBufferUchar, NdisRawWritePortBufferUlong, NdisRawWritePortBufferUshort, NdisReleaseSpinLock, NdisUnchainBufferAtBack, NdisUnchainBufferAtFront


NdisQueryBufferOffset

This function retrieves the base virtual address of the range specified in a specified buffer descriptor.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisQueryBufferOffset(IN PNDIS_BUFFER Buffer,
OUT PUINT Offset, OUT PUINT Length);

Parameters

Buffer
Pointer to the buffer descriptor.
Offset
Pointer to a caller-supplied variable in which this function returns the 0-based byte offset within the physical page containing the buffer.
Length
Pointer to a caller-supplied variable in which this function returns the size, in bytes, of the given buffer.

Remarks

This function returns the offset within a physical page at which a given buffer begins. Usually, the buffer descriptor is part of a packet chain.

This function runs faster than the NdisQueryBuffer function. NDIS drivers call this function in situations in which they need to constrain packets by certain criteria. For example, this function can be used to determine if a buffer crosses a page boundary, if it is odd-byte aligned, and so on.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

See Also

NdisAllocateBuffer, NdisQueryBuffer, NdisUnchainBufferAtBack, NdisUnchainBufferAtFront


NdisQueryMapRegisterCount

This function returns the maximum number of available map registers in the current platform.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

NDIS_STATUS NdisQueryMapRegisterCount(
IN NDIS_INTERFACE_TYPE BusType, OUT PUINT MapRegisterCount);

Parameters

BusType
Specifies the I/O bus interface type of the caller’s busmaster DMA NIC, which usually is the type of I/O bus on which the NIC is connected, as one of the following:
NdisInterfaceInternal
Specifies a host-specific internal interface.
NdisInterfaceIsa
Specifies the ISA interface.
NdisInterfacePci
Specifies the Peripheral Component Interconnect (PCI) interface.
NdisInterfacePcMcia
Specifies the Personal Computer Memory Card International Association (PCMCIA) interface.
MapRegisterCount
Pointer to a caller-supplied variable in which this function returns the maximum number of map registers available to the caller.

Return Values

Returns NDIS_STATUS_SUCCESS if the value at MapRegisterCount is valid. Otherwise, it returns NDIS_STATUS_NOT_SUPPORTED.

Remarks

Currently, Windows CE does not support direct memory access (DMA). The Windows CE version of this function is a stub that does no work. When Windows CE does support DMA, this function will be more fully developed.


NdisQueryPacket

This function returns information about a specified packet.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisQueryPacket(IN PNDIS_PACKET Packet,
OUT PUINT PhysicalBufferCount OPTIONAL,
OUT PUINT BufferCount OPTIONAL,
OUT PNDIS_BUFFER *FirstBuffer OPTIONAL,
OUT PUINT TotalPacketLength OPTIONAL);

Parameters

Packet
Pointer to a packet descriptor.
PhysicalBufferCount
Pointer to a caller-supplied variable in which this function returns the maximum number of physical breaks mapped by the buffer descriptors chained to the given packet. This parameter can be NULL.
BufferCount
Pointer to a caller-supplied variable in which this function returns the number of buffer descriptors chained to the specified packet. This parameter can be NULL.
FirstBuffer
Pointer to a caller-supplied variable in which this function returns a pointer to the initial buffer descriptor chained to the specified packet. This parameter can be NULL.
TotalPacketLength
Pointer to a caller-supplied variable in which this function returns the number of bytes of packet data mapped by all chained buffer descriptors. This parameter can be NULL.

Remarks

This function returns caller-selected information about a specified packet. The caller must specify at least one of the PhysicalBufferCount, BufferCount, FirstBuffer, and TotalPacketLength pointers, along with the Packet parameter. A caller can specify explicit pointers for all parameters.

Specifying an explicit PhysicalBufferCount pointer is equivalent to summing calls to the NdisGetBufferPhysicalArraySize function for each buffer descriptor in the packet descriptor. A driver can call the NdisGetNextBuffer function as many times as necessary to retrieve pointers to any subsequent buffer descriptors in the chain, unless the call returns 0, indicating that the packet descriptor has no data.

If the caller supplies an explicit BufferCount pointer, this function returns the number of buffer descriptors in the packet chain. The return value can be used as a loop counter to retrieve buffer descriptors in the chain with either of the NdisUnchainBuffer XXX functions.

If the caller supplies an explicit FirstBuffer pointer but the packet’s buffer chain is empty, this function returns NULL at FirstBuffer. Otherwise, the caller can use NdisQueryBuffer subsequently to get details about the initial buffer descriptor for the packet. As a faster alternative, drivers can call NdisGetFirstBufferFromPacket to get a pointer to the initial buffer descriptor.

If the caller supplies an explicit TotalPacketLength pointer, this function returns the total number of bytes specified by every buffer descriptor chained to the specified packet.

A driver that calls this function can run at any IRQL.

See Also

NdisGetFirstBufferFromPacket, NdisGetNextBuffer, NdisQueryBuffer, NdisUnchainBufferAtBack, NdisUnchainBufferAtFront


NdisRawReadPortBufferUchar

This function reads a specified number of bytes into a caller-supplied buffer.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisRawReadPortBufferUchar(IN ULONG Port,
OUT PUCHAR Buffer, IN ULONG Length);

Parameters

Port
Specifies the I/O port. This address falls in a range that was mapped during initialization with the NdisMRegisterIoPortRange function.
Buffer
Pointer to a caller-allocated buffer, in resident memory, into which the bytes are transferred from the NIC’s port. The caller must allocate a buffer at least sizeof(Length).
Length
Specifies how many bytes to transfer from the NIC.

Remarks

This function reads each byte, one at a time, from the given I/O port into the given buffer.

A driver that calls this function can run at any IRQL.

See Also

NdisMRegisterIoPortRange, NdisRawReadPortBufferUlong, NdisRawReadPortBufferUshort, NdisRawReadPortUchar, NdisRawWritePortBufferUchar


NdisRawReadPortBufferUlong

This function reads a specified number of ULONGs into a caller-supplied buffer.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisRawReadPortBufferUlong(IN ULONG Port,
OUT PULONG Buffer, IN ULONG Length);

Parameters

Port
Specifies the I/O port. This address falls in a range that was mapped during initialization with the NdisMRegisterIoPortRange function.
Buffer
Pointer to a caller-allocated buffer, in resident memory, into which the ULONGs are transferred from the NIC. The caller must allocate a buffer at least (sizeof(ULONG) * Length).
Length
Specifies how many ULONGs to transfer from the NIC.

Remarks

This function reads each ULONG value, one at a time, from the given I/O port into the given buffer.

A driver that calls this function can run at any IRQL.

See Also

NdisMRegisterIoPortRange, NdisRawReadPortBufferUchar, NdisRawReadPortBufferUshort, NdisRawReadPortUlong, NdisRawWritePortBufferUlong


NdisRawReadPortBufferUshort

This function reads a specified number of USHORTs into a caller-supplied buffer.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisRawReadPortBufferUshort(IN ULONG Port,
OUT PUSHORT Buffer, IN ULONG Length);

Parameters

Port
Specifies the I/O port. This address falls in a range that was mapped during initialization with the NdisMRegisterIoPortRange function.
Buffer
Pointer to a caller-allocated buffer, in resident memory, into which the USHORTs are transferred from the NIC. The caller must allocate a buffer at least (sizeof(USHORT) * Length).
Length
Specifies how many USHORTs to transfer from the NIC.

Remarks

This function reads each USHORT value, one at a time, from the given I/O port into the given buffer.

A driver that calls this function can run at any IRQL.

See Also

NdisMRegisterIoPortRange, NdisRawReadPortBufferUchar, NdisRawReadPortBufferUlong, NdisRawReadPortUshort, NdisRawWritePortUshort


NdisRawReadPortUchar

This function reads a byte from a given I/O port on the NIC.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisRawReadPortUchar(IN ULONG Port, OUT PUCHAR Data);

Parameters

Port
Specifies the I/O port. This address falls in a range that was mapped during initialization with the NdisMRegisterIoPortRange function.
Data
Pointer to a caller-supplied variable in which this function returns a byte read in from the port.

Remarks

This function runs faster than the NdisImmediateReadPortUchar function because it need not map a bus-relative I/O port address onto a host-dependent logical port address at every call.

A driver that calls this function can run at any IRQL.

See Also

NdisMRegisterIoPortRange, NdisRawReadPortBufferUchar, NdisRawReadPortUlong, NdisRawReadPortUshort, NdisRawWritePortUchar


NdisRawReadPortUlong

This function reads a ULONG value from a given I/O port on the NIC.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisRawReadPortUlong(IN ULONG Port, OUT PULONG Data);

Parameters

Port
Specifies the I/O port. This address falls in a range that was mapped during initialization with the NdisMRegisterIoPortRange function.
Data
Pointer to a caller-supplied variable in which this function returns a ULONG value read in from the port.

Remarks

This function runs faster than the NdisImmediateReadPortUlong function because it need not map a bus-relative I/O port address onto a host-dependent logical port address at every call.

A driver that calls this function can run at any IRQL.

See Also

NdisMRegisterIoPortRange, NdisRawREadPortBufferUlong, NdisRawReadPortUchar, NdisRawReadPortUshort, NdisRawWritePortUlong


NdisRawReadPortUshort

This function reads a USHORT value from a specified I/O port on the NIC.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisRawReadPortUshort(IN ULONG Port, OUT PUSHORT Data);

Parameters

Port
Specifies the I/O port. This address falls in a range that was mapped during initialization with the NdisMRegisterIoPortRange function.
Data
Pointer to a caller-supplied variable in which this function returns a USHORT value read in from the port.

Remarks

This function runs faster than the NdisImmediateReadPortUshort function because it need not map a bus-relative I/O port address onto a host-dependent logical port address at every call.

A driver that calls this function can run at any IRQL.

See Also

NdisMRegisterIoPortRange, NdisRawReadPortBufferUshort, NdisRawReadPortUchar, NdisRawReadPortUlong, NdisRawWritePortUshort


NdisRawWritePortBufferUchar

This function writes a specified number of bytes from a caller-supplied buffer to a given I/O port.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisRawWritePortBufferUchar(IN ULONG Port,
IN PUCHAR Buffer, IN ULONG Length);

Parameters

Port
Specifies the I/O port. This address falls in a range that was mapped during initialization with the NdisMRegisterIoPortRange function.
Buffer
Pointer to a caller-allocated resident buffer containing the bytes to be written.
Length
Specifies the number of bytes to write to the I/O port.

Remarks

An NIC driver calls this function to transfer a sequence of bytes, one at a time, to its NIC.

This function runs significantly faster than the NdisImmediateWritePortBufferUchar function because it need not map a bus-relative port address onto a host-dependent logical port address at every call.

A driver that calls this function can run at any IRQL.

See Also

NdisMRegisterIoPortRange, NdisRawReadPortBufferUchar, NdisRawWritePortBufferUlong, NdisRawWritePortBufferUshort, NdisRawWritePortUchar


NdisRawWritePortBufferUlong

This function writes a specified number of ULONG values from a caller-supplied buffer to a given I/O port.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisRawWritePortBufferUlong(IN ULONG Port,
IN PULONG Buffer, IN ULONG Length);

Parameters

Port
Specifies the I/O port. This address falls in a range that was mapped during initialization with the NdisMRegisterIoPortRange function.
Buffer
Pointer to a caller-allocated resident buffer containing the ULONGs to be written.
Length
Specifies the number of ULONGs to write to the I/O port.

Remarks

An NIC driver calls this function to transfer a sequence of ULONGs, one at a time, to its NIC.

This function runs significantly faster than the NdisImmediateWritePortBufferUlong function because it need not map a bus-relative port address onto a host-dependent logical port address at every call.

A driver that calls this function can run at any IRQL.

See Also

NdisMRegisterIoPortRange, NdisRawReadPortBufferUlong, NdisRawWritePortBufferUchar, NdisRawWritePortBufferUshort, NdisRawWritePortUlong


NdisRawWritePortBufferUshort

This function writes a specified number of USHORT values from a caller-supplied buffer to a given I/O port.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisRawWritePortBufferUshort(IN ULONG Port,
IN PUSHORT Buffer, IN ULONG Length);

Parameters

Port
Specifies the I/O port. This address falls in a range that was mapped during initialization with the NdisMRegisterIoPortRange function.
Buffer
Pointer to a caller-allocated resident buffer containing the USHORTs to be written.
Length
Specifies the number of USHORTs to write to the I/O port.

Remarks

An NIC driver calls this function to transfer a sequence of USHORTs, one at a time, to its NIC.

This function runs significantly faster than the NdisImmediateWritePortBufferUshort function because it need not map a bus-relative port address onto a host-dependent logical port address at every call.

A driver that calls this function can run at any IRQL.

See Also

NdisMRegisterIoPortRange, NdisRawReadPortBufferUshort, NdisRawWritePortBufferUchar, NdisRawWritePortBufferUlong, NdisRawWritePortUshort


NdisRawWritePortUchar

This function writes a byte to an I/O port on the NIC.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisRawWritePortUchar(IN ULONG Port, IN UCHAR Data);

Parameters

Port
Specifies the I/O port. This address falls in a range that was mapped during initialization with the NdisMRegisterIoPortRange function.
Data
Specifies the byte to be written.

Remarks

This function runs faster than the NdisImmediateWritePortUchar function because it need not map a bus-relative I/O port address onto a host-dependent logical port address at every call.

A driver that calls this function can run at any IRQL.

See Also

NdisMRegisterIoPortRange, NdisRawReadPortUchar, NdisRawWritePortBufferUchar, NdisRawWritePortUlong, NdisRawWritePortUshort


NdisRawWritePortUlong

This function writes a ULONG value to an I/O port on the NIC.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisRawWritePortUlong(IN ULONG Port, IN ULONG Data);

Parameters

Port
Specifies the I/O port. This address falls in a range that was mapped during initialization with the NdisMRegisterIoPortRange function.
Data
Specifies the ULONG to be written.

Remarks

This function runs faster than the NdisImmediateWritePortUlong function because it need not map a bus-relative I/O port address onto a host-dependent logical port address at every call.

A driver that calls this function can run at any IRQL.

See Also

NdisMRegisterIoPortRange, NdisRawReadPortUlong, NdisRawWritePortBufferUlong, NdisRawWritePortUchar, NdisRawWritePortUshort


NdisRawWritePortUshort

This function writes a USHORT value to an I/O port on the NIC.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisRawWritePortUshort(IN ULONG Port, IN USHORT Data);

Parameters

Port
Specifies the I/O port. This address falls in a range that was mapped during initialization with the NdisMRegisterIoPortRange function.
Data
Specifies the USHORT to be written.

Remarks

This function runs faster than the NdisImmediateWritePortUshort function because it need not map a bus-relative I/O port address onto a host-dependent logical port address at every call.

A driver that calls this function can run at any IRQL.

See Also

NdisMRegisterIoPortRange, NdisRawReadPortUshort, NdisRawWritePortBufferUshort, NdisRawWritePortUchar, NdisRawWritePortUlong


NdisReadConfiguration

This function returns the value of a named entry of the specified type from the registry, as long as it has the handle to an open registry key.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisReadConfiguration(OUT PNDIS_STATUS Status,
OUT PNDIS_CONFIGURATION_PARAMETER *ParameterValue,
IN NDIS_HANDLE ConfigurationHandle, IN PNDIS_STRING Keyword,
IN NDIS_PARAMETER_TYPE ParameterType);

Parameters

Status
Pointer to a caller-supplied variable in which this function returns the status of the call as one of the following:
NDIS_STATUS_SUCCESS
The buffer specified at ParameterValue contains the returned configuration information.
NDIS_STATUS_RESOURCES
NDIS could not allocate resources, usually enough memory, to return the requested information.
NDIS_STATUS_FAILURE
The requested information could not be found under the opened registry key designated by the ConfigurationHandle.
ParameterValue
Pointer to a caller-supplied variable in which a successful call to this function returns a pointer to an NDIS_CONFIGURATION_PARAMETER structure.
ConfigurationHandle
Handle returned by NdisOpenConfiguration to an NIC driver’s XXX\DriverName\Parameters registry key or by NdisOpenProtocolConfiguration to a protocol’s XXX\NICDriverInstance\Parameters\ProtocolName key in the protocol section of the registry.
Keyword
Pointer to a caller-supplied counted string, in the system-default character set, specifying the name of the entry under the open registry key for which to return the value.

This parameter can also point to one of the following predefined global keywords for all NDIS drivers:

  • Environment
  • ProcessorType
ParameterType
Specifies the type of the value entry as one of the following:
NdisParameterInteger
Specifies an integer in decimal notation.
NdisParameterHexInteger
Specifies an integer in hexadecimal notation.
NdisParameterString
Specifies a string of type NDIS_STRING.
NdisParameterMultiString
Specifies a multistring parameter of the Windows NT-defined REG_MULTI_SZ type.

Remarks

Every NDIS driver can set up configuration information in the registry for itself under the driver’s Parameters key, using an installation script. For example, a protocol driver might store its own name as an entry with a preformatted string value that can be passed in calls to the NdisRegisterProtocol function.

Each NIC driver also has associated value entries under the driver’s Parameters registry key. The value entries for any particular NIC driver can be device-dependent in nature. For example, an Ethernet NIC driver might have keywords such as InterruptNumber, SharedMemoryAddress, and MulticastListSize. The value associated with such an NDIS keyword can be either an integer (ULONG-type) or a string (NDIS_STRING-type). For example, the set of possible values for the InterruptNumber entry mentioned might be NdisParameterInteger values 2, 3, 4, or 5, or the equivalents in hexadecimal as NdisParameterHexInteger values.

This function buffers and copies the caller-supplied string at Keyword and releases the storage it allocates for this copy before it returns control to the caller. The memory it allocates for the NDIS_CONFIGURATION_PARAMETER structure is freed when the driver releases the ConfigurationHandle with the NdisCloseConfiguration function. The caller of this function is responsible for releasing the buffered string at Keyword.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisAnsiStringToUnicodeString, NdisCloseConfiguration, NdisFreeString, NdisInitAnsiString, NdisInitializeString, NdisInitUnicodeString, NdisOpenConfiguration, NdisOpenProtocolConfiguration, NdisReadNetworkAddress, NdisUnicodeStringToAnsiString, NdisWriteConfiguration


NdisReadNetworkAddress

This function returns the software-configurable network address that was stored in the registry for an NIC when it was installed in the machine.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisReadNetworkAddress(OUT PNDIS_STATUS Status,
OUT PVOID *NetworkAddress, OUT PUINT NetworkAddressLength,
IN NDIS_HANDLE ConfigurationHandle);

Parameters

Status
Pointer to a caller-supplied variable in which this function returns the status of the call as one of the following:
NDIS_STATUS_SUCCESS
The caller can use the address returned at NetworkAddress for its NIC.
NDIS_STATUS_FAILURE
There was no NIC address information available in the caller’s registry Parameters key, or the value stored was not a string.
NetworkAddress
Pointer to a caller-supplied variable in which this function returns a pointer to the buffered network address, stored as a sequence of byte integers, if the call is successful.
NetworkAddressLength
Pointer to a caller-supplied variable in which this function returns the number of bytes returned at NetworkAddress.
ConfigurationHandle
Handle returned by the NdisOpenConfiguration function.

Remarks

For PC Card NICs, if no network address was specified in the registry, NDIS reads the network address from the card’s attribute space and stores it in the registry.

This function searches the registry Parameters key designated by the specifiedd ConfigurationHandle for the keyword NetworkAddress, converts the value of this string-type entry into a sequence of byte integers, and stores the requested information internally. The storage that NDIS allocates for such an address remains valid until the NIC driver calls NdisCloseConfiguration, which frees the memory.

The caller cannot use the variable at NetworkAddress as a pointer unless this function returns NDIS_STATUS_SUCCESS at Status.

The installation program for an NIC that supports software-configurable network addressing stores a value entry named with the NetworkAddress keyword in the appropriate XXX\DriverName\Parameters key of the registry.

An NIC installer usually stores the value of a NetworkAddress entry in the registry as a string of hexadecimal digits. Optionally, an installer can store such an address as a string of paired digits, with each pair separated from the next by a hyphen. This function discards hyphens and converts each such pair into a single byte.

In either form, this function converts the address specified as a string, one character at a time, into the equivalent integer until the string is exhausted.

In the Windows CE registry, such an installed address string contains Unicode characters.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisCloseConfiguration, NdisOpenConfiguration


NdisReadPciSlotInformation

This function returns bus-specific PCI configuration information from the PCI configuration space for a device at a particular socket on the bus.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

ULONG NdisReadPciSlotInformation(
IN NDIS_HANDLE NdisAdapterHandle, IN ULONG SlotNumber,
IN ULONG Offset, IN PVOID Buffer, IN ULONG Length);

Parameters

NdisAdapterHandle
Specifies the MiniportAdapterHandle passed in to the MiniportInitialize function and to most other Miniport XXX functions.
SlotNumber
Specifies the slot number of an NIC on the I/O bus.
Offset
Specifies the byte offset within the PCI configuration space at which to begin transferring the configuration information.
Buffer
Points to a caller-allocated buffer in which to return the requested configuration information.
Length
Specifies the size, in bytes, of the buffer at Buffer and, therefore, how many bytes of configuration information to return.

Return Values

Returns how many bytes of configuration information it returned at Buffer.

Remarks

This function helps a driver find an NIC that it supports on a PCI bus. When it does, the driver can call the NdisMPciAssignResources function to determine the bus-relative configuration parameters that it can use in subsequent calls to other NDIS configuration functions, such as NdisMRegisterInterrupt, NdisMMapIoSpace, and NdisMRegisterIoPortRange.

This function returns the same bus-relative PCI configuration information as NdisImmediateReadPciSlotInformation. However, callers of this function pass the MiniportAdapterHandle passed to the MiniportInitialize function, rather than the WrapperConfigurationContext handle.

The caller is responsible for releasing the memory at Buffer when the driver has consumed the configuration information with NdisFreeMemory.

Miniport drivers call this function from their MiniportInitialize functions.

A driver that calls this function can run at IRQL <= DISPATCH_LEVEL. Usually, callers are running at IRQL PASSIVE_LEVEL.

See Also

NdisFreeMemory, NdisMMapIoSpace, NdisMPciAssignResources, NdisMRegisterInterrupt, NdisMRegisterIoPortRange, NdisMSetAttributes, NdisMSetAttributesEx, NdisOpenConfiguration


NdisRecalculatePacketCounts

This function resets the valid counts for a given packet.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisRecalculatePacketCounts(IN OUT PNDIS_PACKET Packet);

Parameters

Packet
Pointer to the packet descriptor.

Remarks

If a driver explicitly modifies a buffer descriptor chain for a packet descriptor, that driver should call this function with the modified packet. In general, any NDIS driver should avoid modifying buffer descriptor chains that it sets up, and any driver must not modify chains set up by other drivers.

This call resets the valid counts for the packet to FALSE, thus forcing NdisQueryPacket to recalculate the buffer count for the modified packet if it is called subsequently with that packet.

A driver that calls this function can run at any IRQL.

See Also

NdisQueryPacket, NdisReinitializePacket


NdisRegisterProtocol

This function registers an NDIS driver’s Protocol_* entry points and name with the NDIS library when the driver initializes.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisRegisterProtocol(OUT PNDIS_STATUS Status,
OUT PNDIS_HANDLE NdisProtocolHandle,
IN PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics,
IN UINT CharacteristicsLength);

Parameters

Status
Pointer to a caller-supplied variable that can be one of the following values on return from this function:
NDIS_STATUS_SUCCESS
The NDIS library registered the caller as a protocol driver.
NDIS_STATUS_BAD_CHARACTERISTICS
The CharacteristicsLength is too small for the MajorNdisVersion specified in the buffer at ProtocolCharacteristics.
NDIS_STATUS_BAD_VERSION
The MajorNdisVersion specified in the buffer at ProtocolCharacteristics is invalid.
NDIS_STATUS_RESOURCES
A shortage of resources, possibly memory, prevented the NDIS library from registering the caller.
NdisProtocolHandle
Pointer to a caller-supplied variable in which this function returns a handle representing the registered driver.
ProtocolCharacteristics
Pointer to an NDIS_PROTOCOL_CHARACTERISTICS structure set up by the caller.
CharacteristicsLength
Specifies the size, in bytes, of the structure at ProtocolCharacteristics. If the build directive NDIS40 is specified in the sources ahead of #include ndis.h, this value is supplied automatically.

Remarks

The value supplied at CharacteristicsLength must be at least the sizeof(NDISXXX_PROTOCOL_CHARACTERISTICS) designated by the supplied MajorNdisVersion in this structure.

For the best possible performance, any protocol that layers itself above an NIC driver that supports multipacket receives should provide a ProtocolReceivePacket function. Any NIC driver that supports multipacket sends is also likely to indicate multipacket receives. A driver that provides a ProtocolReceivePacket function must also provide a ProtocolReceive function.

After a successful call to this function, a driver cannot alter the set of Protocol XXX functions it supplied.

A successfully registered driver saves the handle returned at NdisProtocolHandle. It is a required parameter to other NDIS functions that the driver calls subsequently.

After a successful call to this function, the driver can call the NdisOpenAdapter function to set up a binding to the underlying NIC driver or to layer itself above any NDIS driver that registered a set of NDIS upper-edge (Miniport XXX) functions.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisDeregisterProtocol, NdisInitializeString, NdisInitUnicodeString, NdisOpenAdapter, NdisZeroMemory


NdisReinitializePacket

This function removes any chained buffers from a given packet and reinitializes it for reuse.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisReinitializePacket(IN OUT PNDIS_PACKET Packet);

Parameters

Packet
Pointer to the packet descriptor allocated by the caller.

Remarks

This function reinitializes a packet descriptor so that the MiniportReserved and ProtocolReserved arrays contain all 0s and the head of the buffer chain is set to NULL.

A driver can call this function only with packet descriptors allocated by that driver. For example, a MiniportReturnPacket function is likely to call this function to prepare a driver-allocated packet for use in a subsequent receive indication.

Before calling this function, a driver must call the NdisFreeBuffer or the NdisUnchainBufferAt XXX functions as many times as necessary to release or to save all buffer descriptors chained to the packet. Otherwise, a call to this function causes a memory leak: all memory associated with the buffer descriptor chain cannot be used by NDIS nor by the driver until the system is rebooted.

A driver can call the NdisQueryPacket function to determine how many buffer descriptors are chained to a given packet and, therefore, how many calls to NdisFreeBuffer or NdisUnchainBufferAt XXX are required. It can call the NdisGetNextBuffer function to retrieve each buffer descriptor pointer to pass to NdisFreeBuffer.

A call to this function has no effect on the NDIS_PACKET_OOB_DATA structure associated with the packet descriptor. To prepare this block for reuse, the allocating driver can reset the relevant members with the appropriate NDIS_SET_PACKET_XXX macro(s).

A driver that calls this function can run at any IRQL.

See Also

NdisAllocatePacket, NdisFreeBuffer, NdisGetNextBuffer, NdisQueryPacket, NDIS_SET_PACKET_HEADER_SIZE, NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO, NDIS_SET_PACKET_STATUS, NDIS_SET_PACKET_TIME_RECEIVED, NDIS_SET_PACKET_TIME_TO_SEND, NdisUnchainBufferAtBack, NdisUnchainBufferAtFront, NdisZeroMemory


NdisReleaseSpinLock

This function releases a spin lock that was acquired in a preceding call to the NdisAcquireSpinLock function.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisReleaseSpinLock(IN PNDIS_SPIN_LOCK SpinLock);

Parameters

SpinLock
Pointer to the acquired spin lock to be released.

Remarks

In Windows CE, NDIS spin locks are implemented using critical sections.

A driver must initialize its spin lock with the NdisAllocateSpinLock function before it calls any other Ndis XXX SpinLock function to access the resources protected by that spin lock.

A driver must call the NdisAcquireSpinLock function to acquire the spin lock before it can call this function. Each call to NdisAcquireSpinLock requires a reciprocal call to this function before the driver can call NdisAcquireSpinLock again.

This function restores the original IRQL at which its caller was running before the call to NdisAcquireSpinLock.

Any spin lock acquired with NdisAcquireSpinLock must be released with this function. Any spin lock acquired with the NdisDprAcquireSpinLock function must be released with the NdisDprReleaseSpinLock function.

A driver that calls this function is running at IRQL DISPATCH_LEVEL.

See Also

NdisAcquireSpinLock, NdisDprAcquireSpinLock


NdisRequest

This function forwards a request to the underlying driver for it to query the capabilities or status of its NIC or that it set the state of its NIC.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisRequest(OUT PNDIS_STATUS Status,
IN NDIS_HANDLE NdisBindingHandle, IN PNDIS_REQUEST NdisRequest);

Parameters

Status
Pointer to a caller-supplied variable that is set on return from this function. The underlying driver determines which NDIS_STATUS_XXX is returned, but it is usually one of the following values:
NDIS_STATUS_SUCCESS
The requested operation completed successfully.
NDIS_STATUS_PENDING
The request is being handled asynchronously, and the caller’s ProtocolRequestComplete function will be called when it is completed.
NDIS_STATUS_INVALID_OID
The OID_XXX code specified in the Oid member of the NDIS_REQUEST-structured buffer at NdisRequest is invalid or unsupported by the underlying driver.
NDIS_STATUS_INVALID_LENGTH or NDIS_STATUS_BUFFER_TOO_SHORT
The value specified in the InformationBufferLength member of the NDIS_REQUEST-structured buffer at NdisRequest does not match the requirements for the given OID_XXX code. If the information buffer is too small, the BytesNeeded member contains the correct value for InformationBufferLength on return from this function.
NDIS_STATUS_INVALID_DATA
The data supplied at InformationBuffer in the given NDIS_REQUEST structure is invalid for the given OID_XXX code.
NDIS_STATUS_NOT_SUPPORTED or NDIS_STATUS_NOT_RECOGNIZED
The underlying driver does not support the requested operation.
NDIS_STATUS_RESOURCES
The request could not be satisfied due to a resource shortage. Usually, this return indicates that an attempt to allocate memory was unsuccessful, but it does not necessarily indicate that the same request, submitted later, will fail for the same reason.
NDIS_STATUS_NOT_ACCEPTED
The underlying driver attempted the requested operation, usually a set, on its NIC but it was failed by the netcard. For example, an attempt to set too many multicast addresses might cause the return of this value.
NDIS_STATUS_CLOSING or NDIS_STATUS_CLOSING_INDICATING
The underlying driver failed the requested operation because a close is in progress.
NDIS_STATUS_RESET_IN_PROGRESS
The underlying NIC driver cannot satisfy the request at this time because it is currently resetting the netcard. The caller’s ProtocolStatus function was or will be called with NDIS_STATUS_RESET_START to indicate that a reset is in progress. This return value does not necessarily indicate that the same request, submitted later, will fail for the same reason.
NDIS_STATUS_FAILURE
This value is usually a nonspecific default, returned when none of the more specific NDIS_STATUS_XXX caused the underlying driver to fail the request.
NdisBindingHandle
Handle returned by the NdisOpenAdapter function that identifies the target NIC or the virtual adapter of the next-lower driver to which the caller is bound.
NdisRequest
Pointer to a buffered structure specifying the operation requested with a given OID_XXX code for either a query or a set.

Remarks

The Windows CE version of this function does not handle statistics requests in which NdisRequest == NdisRequestQueryStatistics. For query and set requests, this function intercepts OID_GEN_CURRENT_PACKET_FILTER, OID_GEN_CURRENT_LOOKAHEAD, OID_GEN_PROTOCOL_OPTIONS, and OID_802_3_MULTICAST_LIST. All others are passed to the miniport driver.

A protocol driver must allocate sufficient memory for the information buffer associated with the OID_XXX of the operation it requests. The driver also must allocate and set up the buffer at NdisRequest before it calls this function. Both buffers must be allocated from nonpaged pool because the underlying driver runs at raised IRQL while processing the request.

For callers layered above an intermediate NDIS driver, this function forwards a request to the next-lower driver that it return information about its own capabilities or directs that driver to handle specific functionality in a caller-determined manner. If the next-lower driver is an NDIS intermediate driver, it can call this function with an OID-specific request of its own before completing the request originally submitted by the higher-level protocol.

Some errors returned at Status are recoverable, including the following:

  • NDIS_STATUS_INVALID_OID
  • NDIS_STATUS_INVALID_LENGTH
  • NDIS_STATUS_BUFFER_TOO_SHORT
  • NDIS_STATUS_INVALID_DATA
  • NDIS_STATUS_RESOURCES
  • NDIS_STATUS_RESET_IN_PROGRESS

This means that a driver can modify the packet at NdisRequest appropriately to correct the OID_XXX code and/or the size or contents of the buffer at InformationBuffer and resubmit the request packet to this function. The same packet might be satisfied on resubmission to this function if the original call indicated a reset in progress or that a resource shortage, which might be temporary, prevented that request from being carried out.

The NDIS library maintains bindings for underlying miniport drivers. NDIS can return information for binding-specific queries if a specified object identifier is associated with a system-defined medium type for which the system provides a filter library.

A driver that calls this function can be running at IRQL <= DISPATCH_LEVEL.

See Also

NdisOpenAdapter


NdisReset

This function forwards a reset request to an underlying driver.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisReset(OUT PNDIS_STATUS Status,
IN NDIS_HANDLE NdisBindingHandle);

Parameters

Status
Pointer to a caller-supplied variable that is set on return from this function. The underlying driver determines which NDIS_STATUS_XXX is returned, but it is usually one of the following values:
NDIS_STATUS_SUCCESS
The underlying driver reset its NIC or virtual NIC to its initial state.
NDIS_STATUS_PENDING
The request is being handled asynchronously, and the caller’s ProtocolResetComplete function will be called when it is completed.
NDIS_STATUS_RESET_IN_PROGRESS
The underlying driver is currently resetting its NIC, so this request is superfluous. Moreover, the caller’s ProtocolStatus function was or will be called with NDIS_STATUS_RESET_START to indicate that a reset is in progress.
NDIS_STATUS_NOT_RESETTABLE
The underlying NIC cannot be reset by software commands.
NDIS_STATUS_ADAPTER_REMOVED or NDIS_STATUS_FAILURE
The caller’s binding is already closed, so no reset will be attempted for this caller.
NDIS_STATUS_CLOSING
The caller’s binding is currently being closed, so no reset will be attempted for this caller.
NDIS_STATUS_SOFT_ERRORS
The underlying NIC driver reset the netcard, but one or more recoverable hardware errors occurred during this operation. The NIC driver has logged the error(s).
NDIS_STATUS_HARD_ERRORS
The underlying NIC driver attempted to reset the netcard, but one or more unrecoverable hardware errors occurred during this operation. The NIC driver has logged the error(s).
NDIS_STATUS_NOT_ACCEPTED
This value usually is a nonspecific default, returned when none of the more specific NDIS_STATUS_XXX caused NDIS or the underlying NIC driver to fail the request.
NdisBindingHandle
Handle returned by the NdisOpenAdapter function that identifies the target NIC or the virtual adapter of the next-lower driver to which the caller is bound.

Remarks

The Windows CE version of this function always forwards reset requests to the underlying driver without waiting until the driver’s internal queues have been cleared.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.


NdisResetComplete

This function forwards a reset request to an underlying driver.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisReset(OUT PNDIS_STATUS Status,
IN NDIS_HANDLE NdisBindingHandle);

Remarks

This function is enabled in Windows CE 2.10 and later versions of Windows CE.


NdisReturnPackets

This function releases ownership of one or more packets after a protocol has consumed the received data.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisReturnPackets(IN PNDIS_PACKET *PacketsToReturn,
IN UINT NumberOfPackets);

Parameters

PacketsToReturn
Pointer to an array of pointers to packet descriptors to be returned to the underlying driver that allocated them for a receive indication.
NumberOfPackets
Specifies the number of pointers in the array.

Remarks

An NDIS intermediate driver should call this function as soon as possible after its ProtocolReceivePacket function has returned control. Otherwise, both the underlying driver that supports multipacket receive indications and the bound protocol driver that processes them suffer a performance degradation.

When an underlying NIC driver runs low on available packet pool for receive indications or its NIC runs low on empty receive buffers, the miniport can force the NDIS library to call every bound protocol driver’s ProtocolReceive function with a single packet descriptor at a time until the miniport has regained ownership of its packet descriptors and the NIC has receive buffers available for incoming net packets. A ProtocolReceive function cannot begin postprocessing a packet of received data and forwarding the processed data to clients until the driver’s ProtocolReceiveComplete function is called.

For a packet descriptor passed in to its ProtocolReceivePacket function, a highest level protocol driver can process its copy of received data and forward the processed data to clients immediately because the protocol can control how long it retains ownership of the resources allocated by the indicating driver. Assuming a highest-level protocol driver does not manipulate the data that it indicates to its clients, the protocol can even set up the range of data within the receive buffer of interest to its client, and make a receive indication to its client(s) by forwarding the input packet descriptor to those clients.

If an intermediate protocol driver’s ProtocolReceivePacket function returns a nonzero reference count to an input packet descriptor, that driver must call this function one or more times. When it has called this function with a particular packet descriptor as many times as the value returned by ProtocolReceivePacket, the NDIS library returns the packet descriptor to the driver that made the indication. For a highest-level protocol that forwards an input packet descriptor to its clients, those clients return the packet descriptor to the NDIS driver that allocated it by making calls to the TdiReturnChainedReceives function.

A protocol driver can rely on NDIS to manage the reference count for every receive packet passed to ProtocolReceivePacket. When the reference count for a packet descriptor originally set to the return from ProtocolReceivePacket goes to 0, the NDIS library calls the indicating driver’s MiniportReturnPacket function with the released packet descriptor.

This function cannot be called from ProtocolReceivePacket.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

See Also

NdisAllocatePacket, NdisFreePacket, NdisMIndicateReceivePacket


NdisSend

This function forwards a send request to the underlying driver.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisSend(OUT PNDIS_STATUS Status,
IN NDIS_HANDLE NdisBindingHandle, IN PNDIS_PACKET Packet);

Parameters

Status
Pointer to a caller-supplied variable that is set on return from this function. The underlying driver determines which NDIS_STATUS_XXX is returned, but it is usually one of the following values:
NDIS_STATUS_SUCCESS
The specified packet is being transmitted over the network.
NDIS_STATUS_PENDING
The request is being handled asynchronously, and the caller’s ProtocolSendComplete function will be called when it is completed.
NDIS_STATUS_INVALID_PACKET
The size of the requested transfer is too large for the NIC, or possibly the NIC indicated an erroneous packet transmission to its driver.
NDIS_STATUS_CLOSING
The underlying driver is closing.
NDIS_STATUS_RESET_IN_PROGRESS
The underlying driver is currently resetting the NIC. The caller’s ProtocolStatus function was or will be called with NDIS_STATUS_RESET_START to indicate that a reset is in progress.
NDIS_STATUS_FAILURE
This value is usually a nonspecific default returned when none of the more specific NDIS_STATUS_XXX caused the underlying driver to fail the request.

The specific NDIS_STATUS_XXX returned for device I/O errors that occur during a transmit operation depends on the nature of the NIC and the discretion of the NIC driver writer. For example, a miniport might return NDIS_STATUS_NO_CABLE if its NIC indicates this condition to the driver.

NdisBindingHandle
Handle returned by the NdisOpenAdapter function that identifies the target NIC or the virtual adapter of the next-lower driver to which the caller is bound.
Packet
Pointer to the caller-supplied packet descriptor, allocated with the NdisAllocatePacket function, with chained buffer descriptors mapping buffers containing the data that the underlying NIC driver should transmit over the wire.

Remarks

Before calling this function, a protocol driver can call the NdisSetPacketFlags function to set the flags in the private header, reserved for use by NDIS, of the packet descriptor that it allocated. These flags specify caller-determined information about the requested send operation that is not contained in the packet data. The underlying NIC driver’s MiniportSend function is given the send flags as an input parameter. The meaning of the packet flags bits is medium-specific and defined by the pair of collaborating drivers.

However, such a pair of collaborating drivers can use the NDIS_PACKET_OOB_DATA structure associated with each packet descriptor to communicate far more information than the packet flags can convey. Before calling this function, a protocol can use the NDIS_SET_PACKET_TIME_TO_SEND and/or NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO macros to set up out-of-band information, if any, relevant to the underlying driver in the NDIS_PACKET_OOB_DATA structure associated with the protocol-allocated packet descriptor.

When an underlying driver has insufficient resources to transmit a valid send packet, the driver has two alternatives:

  • Its MiniportSend function can insert the packet into an internal queue and return NDIS_STATUS_PENDING.

    The driver holds the packet queued until resources become available and sends the packet when they are.

  • Its MiniportSend function can return control with NDIS_STATUS_RESOURCES.

    The NDIS library holds such a returned packet in an internal queue for resubmission to the miniport. The miniport indicates its readiness to accept send packets later by calling NdisMSendResourcesAvailable or NdisMSendComplete, whichever call occurs first.

In either of the preceding situations, this function returns NDIS_STATUS_PENDING to the caller, and the driver’s ProtocolSendComplete function is called when the packet is transmitted.

As soon as a protocol calls this function, it relinquishes ownership of the packet descriptor at Packet of all buffers mapped by buffer descriptors that it chained to the packet and of any out-of-band information that it supplied with the packet descriptor. The protocol regains ownership of these resources when the packet is completed with a status other than NDIS_STATUS_PENDING or when its ProtocolSendComplete function is called.

When either occurs, the protocol can call the NdisReinitializePacket function to prepare the packet for reuse after saving the buffer descriptors chained to the packet descriptor with calls to an NdisUnchainBufferAt XXX function. Reusing such a packet descriptor yields better performance than returning the packet to driver-allocated packet pool with the NdisFreePacket function, and then reallocating it for another send later.

An NDIS intermediate driver must repackage incoming sends from still higher level protocols in fresh packet descriptors before passing such a send request to the underlying miniport with this function.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

See Also

NdisAllocateBuffer, NdisAllocatePacket, NdisFreePacket, NdisGetPacketFlags, NdisMSendResourcesAvailable, NdisReinitializePacket, NdisUnchainBufferAtBack, NdisUnchainBufferAtFront


NdisSetPacketFlags

This function sets caller-determined and medium-specific information in the flags of a given packet descriptor.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisSetPacketFlags(IN PNDIS_PACKET Packet, IN UINT Flags);

Parameters

Packet
Pointer to the packet descriptor in which the flags should be set.
Flags
Specifies the value to be set in the flags, which are in the private portion of the packet descriptor reserved for use by NDIS.

For protocols, the format of this value is specific to the medium that the underlying driver selected when the protocol called the NdisOpenAdapter function to set up the binding.

Remarks

Setting the flags in a packet descriptor allows a protocol driver to pass information, usually about a send request, that is not included in the packet data.

A protocol driver usually calls this function to set the flags in packets sent on any medium that transmits data in an expedited manner. Some types of media include flags information in the packet header contained in buffers chained to the send packet. When a protocol driver is bound to an underlying driver for these types of media, a call to this function is unnecessary.

When a bound protocol calls this function, an underlying driver’s MiniportSendPackets function can read these flags only by calling the NdisGetPacketFlags function. For underlying drivers that have MiniportSend functions, a call to NdisGetPacketFlags is unnecessary because the flags are passed as an input parameter to the MiniportSend function.

All packet descriptors allocated with NdisAllocatePacket are 0-initialized, including the flags. If the value returned by NdisGetPacketFlags is 0, the underlying driver can assume that the packet has no protocol-set flags information.

However, protocols can supply far more media-specific information, such as the packet priority, in the out-of-band data block associated with each packet descriptor than a call to this function with a single packet allows.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

See Also

NdisAllocatePacket, NdisOpenAdapter, NdisSend, NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO


NdisSetPhysicalAddressHigh

This function sets the high-order part of a specified physical address to a specified value.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisSetPhysicalAddressHigh(
IN NDIS_PHYSICAL_ADDRESS PhysicalAddress, IN ULONG Value);

Parameters

PhysicalAddress
Specifies a physical address of an OS-dependent size.
Value
Specifies the value to be written into the high-order part of the address.

Remarks

A driver that calls this function can be running at any IRQL.

See Also

NdisGetPhysicalAddressHigh, NdisSetPhysicalAddressLow


NdisSetPhysicalAddressLow

This function sets the low-order part of a specified physical address to a specified value.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisSetPhysicalAddressLow(
IN NDIS_PHYSICAL_ADDRESS PhysicalAddress, IN ULONG Value);

Parameters

PhysicalAddress
Specifies a physical address of an OS-dependent size.
Value
Specifies the value to be written into the low-order part of the address.

Remarks

A driver that calls this function can be running at any IRQL.

See Also

NdisGetPhysicalAddressLow, NdisSetPhysicalAddressHigh


NdisStallExecution

This function stalls the caller on the current processor for a given interval.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisStallExecution(IN UINT MicrosecondsToStall);

Parameters

MicrosecondsToStall
Specifies the number of microseconds to delay.

Remarks

For the specified MicrosecondsToStall, the caller’s thread of execution stalls on the current processor, consuming CPU cycles. When the specified interval expires, the caller resumes execution.

Unless a driver is running at IRQL >= DISPATCH_LEVEL, it should call the NdisMSleep function, which accepts larger delay intervals without monopolizing a processor for its callers, instead of this function. For example, an NIC driver’s MiniportInitialize function should wait for state changes in the NIC with NdisMSleep.

Both NdisMSleep and this function allow an NIC driver to specify a delay consistently and independently of the clock speed of the host CPU. Neither function involves a timer object used by the NdisSetTimer or the NdisSetPeriodicTimer function. The resolution of the host system clock varies, so very short delays can take slightly longer than the caller of NdisMSleep or this function specified.

A call to this function prevents any other operating system activity on the current processor and prevents system interrupts from occurring during the stall. Therefore, callers should always specify a stall interval of no longer than 50 microseconds.

A driver that calls this function can run at any IRQL.

See Also

NdisMSleep, NdisMSetTimer


NdisTerminateWrapper

This function releases system resources allocated when the NIC driver called the NdisMInitializeWrapper function.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisTerminateWrapper(IN NDIS_HANDLE NdisWrapperHandle,
IN PVOID SystemSpecific);

Parameters

NdisWrapperHandle
Specifies the handle returned by the NdisMInitializeWrapper function.
SystemSpecific
Not used. Set to NULL.

Remarks

A miniport calls this function during initialization if it cannot find an NIC that it supports in the current platform or if it cannot successfully initialize at least one NIC or virtual NIC.

The NDIS library cleans up the resources that it allocated if a miniport driver is unloaded after it has successfully initialized.

A driver should also call this function from its MiniportHalt function when its last NIC is being removed.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisMInitializeWrapper


NdisTransferData

This function forwards a request to copy data received on the underlying NIC into a protocol-supplied packet.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisTransferData(OUT PNDIS_STATUS Status,
IN NDIS_HANDLE NdisBindingHandle, IN NDIS_HANDLE MacReceiveContext, IN UINT ByteOffset, IN UINT BytesToTransfer,
IN OUT PNDIS_PACKET Packet, OUT PUINT BytesTransferred);

Parameters

Status
Pointer to a caller-supplied variable that can be one of the following values on return from this function:
NDIS_STATUS_SUCCESS
The requested data has been transferred into the packet at Packet.
NDIS_STATUS_PENDING
The request is being handled asynchronously, and the caller’s ProtocolTransferComplete function will be called when it is completed.
NDIS_STATUS_RESET_IN_PROGRESS
The underlying driver is currently resetting its NIC or virtual NIC state. The caller’s ProtocolStatus function was or will be called with NDIS_STATUS_RESET_START to indicate that a reset is in progress.
NDIS_STATUS_REQUEST_ABORTED
The caller’s binding is being closed.
NDIS_STATUS_FAILURE
The given ByteOffset and/or the given BytesToTransfer is too large.
NdisBindingHandle
Handle returned by the NdisOpenAdapter function that identifies the target NIC or the virtual adapter of the next-lower driver to which the caller is bound.
MacReceiveContext
Specifies the underlying driver’s handle that was passed as an input parameter to the caller’s ProtocolReceive function. The protocol driver must consider this handle to be opaque.
ByteOffset
Specifies the offset from the start of the receive network packet at which to begin the transfer.
BytesToTransfer
Specifies the number of bytes to transfer. This value can be 0.
Packet
Pointer to the packet descriptor, provided by the caller, into which the underlying NIC driver is to copy the data.
BytesTransferred
Pointer to a caller-supplied variable in which this function returns the number of bytes actually transferred. The value is invalid if this function returns NDIS_STATUS_PENDING at Status.

Remarks

Several protocols can be bound to a single underlying NIC, and each such protocol driver can receive an indication for the same packet. Such a packet is read-only to protocol drivers. Each such driver’s ProtocolReceive function determines whether to make itself a copy of the indicated packet with this function.

Before calling this function, the protocol must allocate a packet descriptor and chain some number of buffer descriptors mapping protocol-allocated buffers into which the underlying driver copies the data. The protocol also might set up the ProtocolReserved part of its packet descriptor before calling this function.

A protocol driver should always allocate its packet descriptors from the packet pool that the driver set up during initialization.

The range requested in a call to this function, specified by ByteOffset and BytesToTransfer, should be suitable to the PacketSize passed in to the caller’s ProtocolReceive function. Callers of this function usually pass a ByteOffset value calculated from the input parameters to ProtocolReceive as (LookaheadBufferRange + 1). That is, ProtocolReceive already consumed the data in the look-ahead buffer, so it calls this function to get the remaining data in the indicated receive packet.

A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.

See Also

NdisMIndicateReceivePacket


NdisUnchainBufferAtBack

This function removes the buffer descriptor at the end of the chain of buffer descriptors for a given packet.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisUnchainBufferAtBack(IN OUT PNDIS_PACKET Packet,
OUT PNDIS_BUFFER *Buffer);

Parameters

Packet
Pointer to the packet descriptor.
Buffer
Pointer to a caller-supplied variable in which this function returns a pointer to the removed buffer descriptor. If no buffer is chained to the specified packet, this variable is set to NULL.

Remarks

This function returns a pointer to the buffer descriptor that it removed from the buffer descriptor chain of the specified packet. It also resets the valid counts for the packet to FALSE, thus forcing the NdisQueryPacket function to recalculate information about the specified packet if it is called subsequently with that packet.

A driver that calls this function can run at any IRQL.

See Also

NdisChainBufferAtBack, NdisQueryPacket, NdisUnchainBufferAtFront


NdisUnchainBufferAtFront

This function removes the buffer descriptor at the head of the chain of buffer descriptors for a specified packet.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisUnchainBufferAtFront(IN OUT PNDIS_PACKET Packet,
OUT PNDIS_BUFFER *Buffer);

Parameters

Packet
Pointer to the packet descriptor.
Buffer
Pointer to a caller-supplied variable in which this function returns a pointer to the removed buffer descriptor. If no buffer is chained to the specified packet, this variable is set to NULL.

Remarks

This function returns a pointer to the buffer descriptor that it removed from the buffer descriptor chain of the specified packet.

It also resets the valid counts for the packet to FALSE, thus forcing the NdisQueryPacket function to recalculate information about the given packet if it is called subsequently with that packet.

A driver that calls this function can run at any IRQL.

See Also

NdisChainBufferAtFront, NdisQueryPacket, NdisUnchainBufferAtBack


NdisUnicodeStringToAnsiString

This function converts a specified counted Unicode string into a counted ASCII string. The translation conforms to the current system locale information.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

NDIS_STATUS NdisUnicodeStringToAnsiString(
IN OUT PNDIS_ANSI_STRING DestinationString,
IN PNDIS_STRING SourceString);

Parameters

DestinationString
Pointer to a caller-allocated buffer in which this function should return the converted ASCII string.
SourceString
Points to the Unicode string to be converted.

Return Values

NDIS_STATUS_SUCCESS indicates success. Otherwise, the contents of the buffer at DestinationString are unaffected.

Remarks

The caller must allocate storage for both the source and destination strings and release these buffers as soon as the strings are no longer needed. The buffer at SourceString must be at least twice the size of that at DestinationString.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisAnsiStringToUnicodeString, NdisInitAnsiString, NdisInitializeString, NdisInitUnicodeString


NdisWriteConfiguration

This function writes a caller-supplied value for a specified entry into the registry.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisWriteConfiguration(OUT PNDIS_STATUS Status,
IN NDIS_HANDLE WrapperConfigurationContext,
IN PNDIS_STRING Keyword,
IN PNDIS_CONFIGURATION_PARAMETER *ParameterValue);

Parameters

Status
Pointer to a caller-supplied variable in which this function returns the status of the call as one of the following:
NDIS_STATUS_SUCCESS
The supplied value at ParameterValue was written into the registry. If this is a new entry, the name at Keyword was also written into the registry.
NDIS_STATUS_NOT_SUPPORTED
The supplied ParameterType is invalid.
NDIS_STATUS_RESOURCES
NDIS could not allocate resources, usually enough memory, to transfer the requested information to the registry.
NDIS_STATUS_FAILURE
The requested information could not be written.
WrapperConfigurationContext
Specifies the handle returned by the NdisOpenConfiguration or the NdisOpenProtocolConfiguration function.
Keyword
Pointer to a caller-supplied counted string, in the system-default character set, specifying the name of an entry for which to write the value.
ParameterValue
Points to a caller-supplied variable set to the address of a filled-in NDIS_CONFIGURATION_PARAMETER structure.

Remarks

If an entry of the same name as at Keyword already exists under the opened registry key, this function replaces its current value with the caller-supplied value. Otherwise, this function adds a new value entry with the specified name and supplied value to the registry.

This function buffers and copies the caller-supplied string at Keyword and the caller-supplied data specified at ParameterValue. This memory is freed when the driver releases the ConfigurationHandle with the NdisCloseConfiguration function. The caller of this function is responsible for releasing the buffered string at Keyword and the memory allocated for the NDIS_CONFIGURATION_PARAMETER structure.

As an alternative to calling this function, every NDIS driver can set up configuration information in the registry for itself under the driver’s Parameters key, using an installation script.

A driver that calls this function runs at IRQL PASSIVE_LEVEL.

See Also

NdisAnsiStringToUnicodeString, NdisCloseConfiguration, NdisFreeMemory, NdisFreeString, NdisInitAnsiString, NdisInitializeString, NdisInitUnicodeString, NdisOpenConfiguration, NdisOpenProtocolConfiguration, NdisReadConfiguration, NdisUnicodeStringToAnsiString


NdisWriteErrorLogEntry

This function writes an entry to the system I/O error log file.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisWriteErrorLogEntry(IN NDIS_HANDLE NdisAdapterHandle,
IN NDIS_ERROR_CODE ErrorCode, IN ULONG NumberOfErrorValues,
IN ULONG …);

Parameters

NdisAdapterHandle
Handle representing the NIC that is the cause of the I/O error to be logged. This handle is an input parameter to the MiniportInitialize function.
ErrorCode
Specifies the NDIS_STATUS_XXX code describing the I/O error.
NumberOfErrorValues
Specifies the number of ULONG values to follow this parameter.
...
Specifies a variable-sized array of ULONGs associated with the error to be logged.

Remarks

Windows CE does not have error-logging facilities. This function does nothing and exists only to enable existing code to compile without errors.


NdisWritePciSlotInformation

This function writes a specified number of bytes to the PCI configuration space for an NIC on the PCI bus.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

ULONG NdisWritePciSlotInformation(
IN NDIS_HANDLE NdisAdapterHandle, IN ULONG SlotNumber,
IN ULONG Offset, IN PVOID Buffer, IN ULONG Length);

Parameters

NdisAdapterHandle
Specifies the MiniportAdapterHandle passed in to the MiniportInitialize function and to most other Miniport XXX functions.
SlotNumber
Specifies the slot number of the NIC on the I/O bus.
Offset
Specifies the byte offset within the PCI configuration space at which to begin transferring the caller-supplied configuration information.
Buffer
Pointer to a caller-allocated buffer containing the PCI configuration information to be written.
Length
Specifies the size, in bytes, of the buffer at Buffer and, therefore, how many bytes of PCI configuration information to write.

Return Values

Returns how many bytes of caller-supplied data it wrote.

Remarks

This function writes PCI configuration information for an NIC. However, drivers of NICs on PCI buses call the NdisImmediateReadPciSlotInformation, NdisReadPciSlotInformation, or NdisMPciAssignResources function far more frequently than this function.

When an NIC driver finds its device on a PCI bus with the Ndis(Immediate)ReadPciSlotInformation function or by retrieving information from the \DriverName\Parameters key in the registry, that driver can call NdisMPciAssignResources to determine the bus-relative configuration parameters to use in subsequent calls to other NDIS configuration functions. If NdisMPciAssignResources returns values that require the driver to reconfigure its device on the bus, it can call this function.

This function transfers the same type of bus-relative PCI configuration information as the NdisImmediateWritePciSlotInformation function. However, callers of this function pass the MiniportAdapterHandle passed in to the MiniportInitialize function, rather than the WrapperConfigurationContext handle.

The caller is responsible for releasing the memory at Buffer when this function returns control.

A driver that calls this function can run at IRQL <= DISPATCH_LEVEL. Usually, callers are running at IRQL PASSIVE_LEVEL.

See Also

NdisFreeMemory, NdisMMapIoSpace, NdisMPciAssignResources, NdisMRegisterInterrupt, NdisMRegisterIoPortRange, NdisMSetAttributes, NdisMSetAttributesEx, NdisReadPciSlotInformation


NdisZeroMappedMemory

This function fills a block of memory that was mapped with a preceding call to the NdisMMapIoSpace function with 0s.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisZeroMappedMemory(IN PVOID Destination, I
N ULONG Length);

Parameters

Destination
Specifies the base virtual address of a block of mapped memory.
Length
Specifies the number of bytes to be filled with 0s.

Remarks

An NIC driver can call this function to 0-initialize mapped device memory. The given Destination and Length must be a proper subrange of the range specified when the driver called the NdisMMapIoSpace function.

This function is optimized, and an NIC driver can call this function any time that it needs to clear a mapped memory range.

A driver that calls this function can run at any IRQL.

See Also

NdisMMapIoSpace, NdisZeroMemory


NdisZeroMemory

This function fills a block of memory with 0s.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

VOID NdisZeroMemory(IN PVOID Destination, IN ULONG Length);

Parameters

Destination
Specifies the base virtual address of a block of memory.
Length
Specifies how many bytes to fill with 0s.

Remarks

This function fills the specified range with 0s. The specified Destination and Length must be a proper subrange of a caller-accessible memory range.

As long as the specified range was allocated from nonpaged pool, the caller can be running at any IRQL. Otherwise, a caller must be running at IRQL < DISPATCH_LEVEL as, for example, when a caller clears a structure that it allocated on the stack.

See Also

NdisAllocateMemory, NdisZeroMappedMemory


NLedDriverDllEntry

This function is the main entry point for the notification LED driver DLL.

Syntax

BOOL NLedDriverDllEntry(HANDLE hinstDll, DWORD fdwReason, LPVOID lpvReserved);

Parameters

hinstDll
Instance handle of the DLL.
fdwReason
Reason for which this function was called.
lpvReserved
Reserved; not used.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function is defined in the Nleddrv.cpp file.


NLedDriverGetDeviceInfo

This function returns information about the notification LED device.

Syntax

BOOL NLedDriverGetDeviceInfo (INT nId, PVOID pOutput);

Parameters

nId
Integer specifying the information to be returned. The following values are defined:
NLED_COUNT_INFO_ID
Indicates that the pOutput buffer specifies the number of notification LEDs on the device.
NLED_SUPPORTS_INFO_ID
Indicates that the pOutput buffer specifies information about the capabilities supported by the notification LED.
NLED_SETTINGS_INFO_ID
Indicates that the pOutput buffer contains information about the notification LED current settings.
pOutput
Pointer to the buffer to which the information is to be returned. The buffer points to various structure types, depending on the value of nId, as detailed in the following table.
Value of nID
Structure in pOutput
NLED_COUNT_INFO_ID | NLED_COUNT_INFO
NLED_SUPPORTS_INFO_ID | NLED_SUPPORTS_INFO
NLED_SETTINGS_INFO_ID | NLED_SETTINGS_INFO

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

Implement this GWES-layer function as part of porting native device drivers.

This function is declared in the Led_drvr.h header file.

See Also

NLED_COUNT_INFO, NLED_SETTINGS_INFO, NLED_SUPPORTS_INFO


NLedDriverInitialize

This function initializes the notification LED.

Syntax

BOOL NLedDriverInitialize (void);

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

Even if no explicit initialization is required for the notification LED, a stub function must be provided.

Implement this GWES-layer function as part of porting native device drivers.

This function is declared in the Led_drvr.h header file.


NLedDriverPowerDown

This function sends a power status change notification to the LED devices.

Syntax

VOID NLedDriverPowerDown (BOOL power_down);

Parameters

power_down
Boolean. TRUE indicates power is turning off. FALSE indicates power is turning on.

Return Values

None.

Remarks

This function can take action as appropriate for the LED devices, such as turning them off.

Implement this GWES-layer function as part of porting native device drivers.

This function is declared in the Led_drvr.h header file.


NLedDriverSetDevice

This function changes the setting of the notification LED.

Syntax

BOOL NLedDriverSetDevice (INT nId, PVOID pInput);

Parameters

nId
Integer that specifies what information is to be set. The following value is defined:
NLED_SETTINGS_INFO_ID
Indicates that the pInput buffer contains information about the current settings for the notification LED.
pInput
Pointer to the buffer that contains the NLED_SETTINGS_INFO structure. This structure contains the new settings.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

Implement this GWES-layer function as part of porting native device drivers.

This function is declared in the Led_drvr.h header file.

See Also

NLED_SETTINGS_INFO


OhcdMdd_CreateMemoryObject

This function creates the OHCI shared memory area.

Syntax

LPVOID OhcdMdd_CreateMemoryObject(DWORD cbSize,
DWORD cbHighPrioritySize, PUCHAR pVirtAddr, PUCHAR pPhysAddr);

Parameters

cbSize
[IN] Specifies the total size of OHCD shared memory area.
cbHighPrioritySize
[IN] Specifies the bytes reserved for high-priority isochronous or interrupt transfers and OHCI host controller communication area.
pVirtAddr
[IN] Pointer to the virtual address, which may be NULL, of a memory area.
pPhysAddr
[IN] Pointer to the physical address, which may be NULL, of a memory area.

Return Value

A pointer to an OHCD memory object indicates success. NULL indicates failure.

Remarks

This function is called by the OHCD PDD to initialize the shared memory area used by the OHCI driver. This memory contains the the Host Controller Communication Area (HCCA) for communicating with the OHCI hardware and is used to allocate DMA buffers for USB driver data transfers. Two options are available. If a platform has an area of memory set aside that can be used by OHCI, as specified in the Config.bib file, it can pass the virtual and physical address pointers in to this function. This is the recommended method. Alternatively, the PDD may pass NULL in for the physical and virtual address pointers, in which case the OhcdMdd_CreateMemoryObject function attempts to allocate a suitable memory buffer from system RAM.

The OHC interface shared memory area is broken into two separate areas: a high-priority pool of buffers for the HCCA and for isochronous client buffers, and a lower-priority pool of buffers for other client transfers.

The size of the shared memory area is dependent on the perceived usage of USB within the platform. The OHC interface controller uses 4-KB page boundaries for internal data structures, so the size should be a multiple of 4 KB and must be at least 8 KB for the control structures and memory needed for device configuration. Additionally, client drivers may need to utilize this area for their transfers, so it is recommended that OEMS provide additional memory. The maximum DMA memory used for a client transfer is 8 KB, so OEMs should try to determine what a reasonable number of outstanding client transfers may be.

A recommended value for general-purpose USB operation is 38 KB, with 20 KB reserved for high-priority transfers. OEMs that anticipate less demand on the USB subsystem can safely reduce this to 28 KB, of which 20 KB is high priority. Reducing the size of the high-priority buffer may cause isochronous transfers to fail if memory cannot be allocated, whereas reducing the size of the non-high-priority buffer reduces performance on bulk transfers. However, reducing the non-high-priority buffer does not cause failures, because bulk transfers can block to wait for memory to become available.

If possible, OEMs should consider placing the OHCD shared memory area in high-speed memory, particularly to support streaming (isochronous) data transfers.

This function is declared in the Ohcdddsi.h header file.


OhcdMdd_DestroyMemoryObject

This function cleans up an OHC interface memory object.

Syntax

BOOL OhcdMdd_DestroyMemoryObject(LPVOID lpvMemoryObject);

Parameters

lpvMemoryObject
[IN] Pointer to an OHCD memory object.

Return Values

TRUE indicates success. FALSE indicates an error.

Remarks

This function is called when an OHC interface controller is removed, or if an error occurs during initialization, to enable the MDD to clean up internal data structures.

This function is declared in the Ohcdddsi.h header file.


OhcdMdd_CreateOhcdObject

This function creates and initializes an OHC interface driver object.

Syntax

LPVOID OhcdMdd_CreateOhcdObject(LPVOID lpvOhcdPddObject, LPVOID lpvMemoryObject, LPCWSTR szRegKey, PUCHAR ioPortBase, DWORD dwSysIntr);

Parameters

lpvOhcdPddObject
[IN] Pointer to the PDD-specific data for this instance.
lpvMemoryObject
[IN] Pointer to the memory object created by the OhcdMdd_CreateMemoryObject function.
szRegKey
[IN] Specifies the registry key where OHC interface configuration settings are stored.
ioPortBase
[IN] Pointer to the OHC interface controller registers.
dwSysIntr
[IN] Specifies the logical value for an OHC interface interrupt (SYSINTR_xx).

Return Values

A pointer to OHC interface driver object indicates success. NULL indicates failure.

Remarks

This function is called by the PDD during initialization to initialize an OHC interface driver object. As part of this processing, the USB driver, Usbd.dll, is loaded, and the OHC interface interrupt is hooked into the system. Next, the OHC interface hardware is placed into OPERATIONAL state, and list processing begins: device attach events are serviced, transfers initiated, and so on.

The Windows CE–based USB subsystem supports multiple host controllers. The PDD should create an OHC interface driver object for each physical host controller in the system.

This function is declared in the Ohcdddsi.h header file.


OhcdMdd_DestroyOhcdObject

This function cleans up an OHC interface driver object.

Syntax

BOOL OhcdMdd_DestroyOhcdObject(LPVOID lpvOhcdObject);

Parameters

lpvOhcdObject
[IN] Pointer to an OHCI driver object.

Return Values

TRUE indicates success. FALSE indicates an error.

Remarks

This function should be called when an OHC interface controller is removed, or if an error occurs during initialization, to enable the MDD to clean up internal data structures.

This function is declared in the Ohcdddsi.h header file.


OhcdMdd_PowerDown

This function is the OHCD MDD power-down handler.

Syntax

BOOL OhcdMdd_PowerDown(LPVOID lpvOhcdObject);

Parameters

lpvOhcdObject
[IN] Pointer to an OHC interface driver object.

Return Values

TRUE indicates success. FALSE indicates an error.

Remarks

This function is called by the PDD as part of processing this function. It causes the MDD to save state and prepare the OHC interface controller to be shut down. The OHC interface controller is placed into reset; SOF generation is disabled.

This function is declared in the Ohcdddsi.h header file.


OhcdMdd_PowerUp

This function is the OHCD MDD power-up handler.

Syntax

BOOL OhcdMdd_PowerUp(LPVOID lpvOhcdObject);

Parameters

lpvOhcdObject
[IN] Pointer to an OHC interface driver object.

Return Values

TRUE indicates success. FALSE indicates an error.

Remarks

This function should be called by the PDD as part of processing this function. It causes the MDD to restore state and reinitialize the OHC interface hardware. All client drivers loaded at the time that the power is turned off are unloaded. Once this is completed, the OHC interface hardware is placed into the OPERATIONAL state, and drivers for devices that are still attached to the USB are loaded.

This function is declared in the Ohcdddsi.h header file.


OhcdPdd_DllMain

This function is the main DLL entry point for the PDD portion of an OHC interface driver.

Syntax

BOOL OhcdPdd_DllMain(HANDLE hinstDLL, DWORD dwReason, LPVOID lpvReserved);

Parameters

hinstDLL
[IN] Handle to a DLL instance.
dwReason
[IN] Specifies a reason code.
lpvReserved
[IN] Pointer to a system parameter.

Return Values

TRUE indicates success. FALSE indicates an error.

Remarks

This function enables the PDD to perform any necessary processing at DLL entry time. Generally, this function does little because most initialization is performed by the OhcdPdd_Init function.

This function is declared in the Ohcdddsi.h header file.


OhcdPdd_Init

This function initializes an OHC interface plus any platform-specific hardware and structures.

Syntax

DWORD OhcdPdd_Init(DWORD dwContext);

Parameters

dwContext
[IN] Pointer to a string indicating the active registry key for the OHCD.

Return Values

A pointer to PDD-specific data structure indicates success. NULL indicates failure.

Remarks

This function is called at system initialization to detect and configure the OHC interface hardware. As part of the processing for this function, the OhcdMdd_CreateOhcdObject function is called to initialize the MDD and OHC interface hardware.

This function is declared in the Ohcdddsi.h header file.


OhcdPdd_CheckConfigPower

This function checks power for a requested configuration.

Syntax

BOOL OhcdPdd_CheckConfigPower(UCHAR bPort,
DWORD dwConfigPower, DWORD dwTotalPower);

Parameters

bPort
[IN] Specifies the root hub port number.
dwConfigPower
[IN] Specifies the power, in milliamps, required by the configuration being checked.
dwTotalPower
[IN] Specifies the power, in milliamps, drawn by other devices on this port.

Return Values

TRUE indicates that the USB system supports the configuration. FALSE indicates that a configuration is not supported.

Remarks

When a device is initially attached to the bus, OHC interface selects a configuration based on the power requirements of the system by calling this function for each configuration until one that is supported is found. If no configurations in a device are supported, the device is not configured.

This enables the platform to perform additional processing if necessary, such as checking whether the Windows CE–based platform is using batteries or external power, or possibly sampling the current system power status.

This function is declared in the Ohcdddsi.h header file.


OhcdPdd_Close

This function is the OHCD close routine.

Syntax

BOOL OhcdPdd_Close(DWORD dwOpenContext);

Parameters

dwOpenContext
[IN] Specifies a pointer to the device context returned from OhcdPdd_Init.

Return Values

For future compatibility, drivers return TRUE.

Remarks

This function is the standard stream interface driver close routine. It currently is unused.

This function is declared in the Ohcdddsi.h header file.


OhcdPdd_Deinit

This function is the OHCD deinitialization routine.

Syntax

BOOL OhcdPdd_Deinit(DWORD dwDeviceContext);

Parameters

dwDeviceContext
[IN] Specifies a pointer to the device context returned from the

OhcdPdd_Init function.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function is called if the OHC interface driver is unloaded. As part of the processing for this function, the OhcdMdd_DestroyOhcdObject function is called to enable the MDD to clean up internal data structures.

This function is declared in the Ohcdddsi.h header file.


OhcdPdd_IOControl

This function is the OHCD IOCTL routine.

Syntax

BOOL OhcdPdd_IOControl(DWORD dwOpenContext);

Parameters

dwOpenContext
[IN] Pointer to the device context returned from the OhcdPdd_Init function.

Return Values

For future compatibility, drivers return FALSE.

Remarks

This function is the standard stream interface driver IOCTL routine. It currently is unused.

This function is declared in the Ohcdddsi.h header file.


OhcdPdd_Open

This function is the OHCD open routine.

Syntax

DWORD OhcdPdd_Open(DWORD dwDeviceContext,
DWORD dwAccessCode, DWORD dwShareMode);

Parameters

dwDeviceContext
[IN] Specifies a pointer to the device context returned from the OhcdPdd_Init function.
dwAccessCode
Not used.
dwShareMode
Not used.

Return Values

For future compatibility, drivers return 1.

Remarks

This function is the standard stream interface driver open routine. It currently is unused.

This function is declared in the Ohcdddsi.h header file.


OhcdPdd_PowerDown

This function is the OHCD power-off handler.

Syntax

void OhcdPdd_PowerDown(DWORD dwDeviceContext);

Parameters

dwDeviceContext
[IN] Specifies a pointer to the device context returned from the OhcdPdd_Init function.

Remarks

This function is called when the system is turned off. This function must call the OhcdMdd_PowerDown function to enable the MDD to save state information. Then, any processing specific to the platform, such as removing power from the host controller hardware, is performed. No system calls can be made from within this function.

This function is declared in the Ohcdddsi.h header file.


OhcdPdd_PowerUp

This function is the OHCD power-up handler.

Syntax

void OhcdPdd_PowerUp(DWORD dwDeviceContext);

Parameters

dwDeviceContext
[IN] Specifies a pointer to the device context returned from the OhcdPdd_Init function.

Remarks

This function is called when the system turned on. This function must call the OhcdMdd_PowerUp function to enable the MDD to restore state information. The OHC interface memory area, as passed to the OhcdMdd_CreateOhcdObject function, must be preserved across a suspend/resume cycle. No system calls may be made from within this function.

This function is declared in the Ohcdddsi.h header file.


OhcdPdd_Read

This function is the OHCD read routine.

Syntax

DWORD OhcdPdd_Read(DWORD dwOpenContext);

Parameters

dwOpenContext
[IN] Specifies a pointer to the device context returned from the OhcdPdd_Init function.

Return Values

For future compatibility, drivers return –1.

Remarks

This function is the standard stream interface driver read routine. It currently is unused.

This function is declared in the Ohcdddsi.h header file.


OhcdPdd_Seek

This function is the OHCD seek routine.

Syntax

DWORD OhcdPdd_Seek(DWORD dwOpenContext);

Parameters

dwOpenContext
[IN] Pointer to the device context returned from the OhcdPdd_Init function.

Return Values

For future compatibility, drivers return –1.

Remarks

This function is the standard stream interface driver seek routine. It currently is unused.

This function is declared in the Ohcdddsi.h header file.


OhcdPdd_Write

This function is the OHCD write routine.

Syntax

DWORD OhcdPdd_Write(DWORD dwOpenContext);

Parameters

dwOpenContext
[IN] Pointer to the device context returned from the OhcdPdd_Init function.

Return Values

For future compatibility, drivers return –1.

Remarks

This function is the standard stream interface driver write routine. It currently is unused.

This function is declared in the Ohcdddsi.h header file.


OpenClientRegistryKey

This function opens a registry key associated with a client driver.

Syntax

HKEY OpenClientRegistryKey(LPCWSTR szUniqueDriverId);

Parameters

szUniqueDriverId
[IN] Specifies a unique driver identifier string.

Return Values

A handle to the appropriate key indicates success. NULL indicates that no key exists for that driver or that some other error occurs.

Remarks

The client key is created in the RegisterClientDriverId function.

This function is defined in the Mousedrv.cpp file.

See Also

RegisterClientDriverId


OpenPipe

This function opens a pipe for communication with a USB device.

Syntax

USB_PIPE OpenPipe(USB_HANDLE hDevice, LPCUSB_ENDPOINT_DESCRIPTOR lpEndpointDescriptor);

Parameters

hDevice
[IN] Handle to a USB device.
lpEndpointDescriptor
[IN] Pointer to an endpoint descriptor.

Return Values

A handle to a USB pipe indicates success. NULL indicates failure.

Remarks

No more than 16 pipes can be open simultaneously on a device, including the default endpoint 0 pipe.

This function is defined in the Mousedrv.cpp file.

See Also

ClosePipe


PDCardGetAdapter

This function returns power-save mode status and capabilities.

Syntax

STATUS PDCardGetAdapter(UINT32 uSocket, PPDCARD_ADAPTER_STATE pState);

Parameters

uSocket
Specifies a number identifying the PC Card socket for which to return information. Valid values depend on the number of PC Card sockets present on the Windows CE–based platform.
pState
Pointer to a PDCARD_ADAPTER_STATE structure containing the socket’s status and capabilities.

Return Values

Returns one of the CERR_* return codes in the Cardserv.h header file.

Remarks

When the system is in low-power mode, the ADP_STATE_POWERDOWN bit is set. When the PC Card socket is powered off, the bit ADP_STATE_POWEROFF is set. When the PC Card socket is in full-power mode, the state is either 0 or ADP_STATE_MAINTAIN. This function is called in critical power situations, so it should not block or yield.


PDCardGetSocket

This function gets the socket state of the specified socket.

Syntax

STATUS PDCardGetSocket(UINT32 uSocket, PPDCARD_SOCKET_STATE pState);

Parameters

uSocket
Specifies the number indicating the socket. The first socket is 0.
pState
Pointer to a PDCARD_SOCKET_STATE structure.

Return Values

Returns one of the CERR_* return codes in the Cardserv.h header file.

Remarks

This function reads the specified socket’s state and returns it in the PDCARD_SOCKET_STATE structure.


PDCardGetWindow

This function reports the current state of a memory or an I/O window.

Syntax

STATUS PDCardGetWindow(UINT32 uWindow, PPDCARD_WINDOW_STATE pWindowState);

Parameters

uWindow
Specifies the number indicating the window. The first window is 0.
pWindowState
Pointer to a PDCARD_WINDOW_STATE structure.

Return Values

Returns one of the CERR_* error values in the Cardserv.h header file.


PDCardInquireAdapter

This function returns the socket controller’s characteristics and capabilities.

Syntax

STATUS PDCardInquireAdapter(PPDCARD_ADAPTER_INFO pAdapterInfo);

Parameters

pAdapterInfo
Pointer to a PDCARD_ADAPTER_INFO structure.

Return Values

Returns one of the CERR_* return codes in the Cardserv.h header file.


PDCardInquireWindow

This function reports the characteristics and capabilities of a memory or I/O window.

Syntax

STATUS PDCardInquireWindow(UINT32 uWindow, PPDCARD_WINDOW_INFO pWinInfo);

Parameters

uWindow
Specifies the number indicating the window. The first window is 0.
pWinInfo
Pointer to a PDCARD_WINDOW_INFO structure.

Return Values

Returns one of the CERR_* error values in the Cardserv.h header file.


PDCardReadAttrByte

This function reads the byte at the specified offset in a card’s attribute memory space.

Syntax

UINT8 PDCardReadAttrByte(PVOID pCardMem, UINT32 uOffset);

Parameters

pCardMem
Pointer to PC Card attribute memory obtained from the CardMapMemory function.
uOffset
Integer setting the offset into the card’s attribute memory.

Return Values

Returns the byte read.

Remarks

This function is called within a try-except statement in case the card is removed and the memory access results in a fault.

See Also

PDCardWriteAttrByte, PDCardReadCmnByte, PDCardWriteCmnByte


PDCardReadCmnByte

This function reads the byte at the specified offset in a card’s common memory space.

Syntax

UINT8 PDCardReadCmnByte(PVOID pCardMem);

Parameters

pCardMem
Pointer to PC Card common memory obtained from the CardMapMemory function.

Return Values

Returns the byte read.

Remarks

This function is called within a try-except statement in case the card is removed and the memory access results in a fault.

See Also

PDCardReadAttrByte, PDCardWriteAttrByte, PDCardWriteCmnByte


PDCardResetSocket

This function resets the specified socket.

Syntax

STATUS PDCardResetSocket(UINT32 uSocket);

Parameters

uSocket
Specifies the number indicating the socket. The first socket is 0.

Return Values

Returns one of the CERR_* return codes in the Cardserv.h header file.


PDCardSetAdapter

This function sets power-save mode status and capabilities.

Syntax

STATUS PDCardSetAdapter(UINT32 uSocket, PPDCARD_ADAPTER_STATE pState);

Parameters

uSocket
Specifies the identifier number of the PC Card socket to modify.
pState
Pointer to the socket’s status and capabilities.

Return Values

Returns one of the CERR_* return codes in the Cardserv.h header file.

Remarks

If the ADP_STATE_POWEROFF bit is set, the PC Card system is turned off. If the ADP_STATE_POWERDOWN bit is set, the PC Card system is placed in power-save mode. In power-save mode, it is expected that card insertion and removal events are detected. If both of these bits are off, the PC Card system is placed in full-power mode. The PDCardSetAdapter function is called in critical power situations, so it should not block or yield.


PDCardSetSocket

This function sets the socket state of the specified socket.

Syntax

STATUS PDCardSetSocket(UINT32 uSocket, PPDCARD_SOCKET_STATE pState);

Parameters

uSocket
Specifies the number indicating the socket. The first socket is 0.
pState
Pointer to the PDCARD_SOCKET_STATE structure.

Return Values

Returns one of the CERR_* return codes in the Cardserv.h header file.

Remarks

This function sets the specified socket’s state and adjusts the socket controller appropriately. Callers typically call the PDCardGetSocketState function first, and after making adjustments, the PDCARD_SOCKET_STATE structure then calls this function. This avoids duplicating the socket state on different layers and unintentionally setting socket parameters.


PDCardSetWindow

This function changes the characteristics of a memory or I/O window.

Syntax

STATUS PDCardSetWindow(UINT32 uWindow, PPDCARD_WINDOW_STATE pWindowState);

Parameters

uWindow
Specifies the number indicating the window. The first window is 0.
pWindowState
Pointer to a PDCARD_WINDOW_STATE structure.

Return Values

Returns one of the CERR_* error values in the Cardserv.h header file.


PDCardWriteAttrByte

This function writes a byte to the specified offset in a card’s attribute memory space.

Syntax

VOID PDCardWriteAttrByte(PVOID pCardMem, UINT32 uOffset, UINT8 uByte);

Parameters

pCardMem
Pointer to PC Card attribute memory obtained from the CardMapMemory function.
uOffset
Integer setting the offset into card’s attribute memory.
uByte
Specifies the byte to be written.

Remarks

This function is called within a try-except statement in case the card is removed and the memory access results in a fault.

See Also

PDCardReadAttrByte, PDCardReadCmnByte, PDCardWriteCmnByte


PDCardWriteCmnByte

This function writes a byte to the specified offset in a card’s common memory space.

Syntax

VOID PDCardWriteCmnByte(PVOID pCardMem, UINT32 uOffset,
UINT8 uByte);

Parameters

pCardMem
Pointer to PC Card common memory obtained from the CardMapMemory function.
uOffset
Integer setting the offset into the card’s common memory.
uByte
Specifies the byte to be written.

Remarks

This function is called within a try-except statement in case the card is removed and the memory access results in a fault.

See Also

PDCardReadAttrByte, PDCardWriteAttrByte, PDCardReadCmnByte


PDD_AudioDeinitialize

This function turns off and disconnects the audio device.

Syntax

VOID PDD_AudioDeinitialize(void);

Return Values

None.

Remarks

This function is called if the audio driver is unloaded from the operating system or if the process of loading the driver fails.

This function is declared in the Waveddsi.h header file.


PDD_AudioGetInterruptType

This function determines the cause of the audio interrupt and returns the current device status.

Syntax

AUDIO_STATE PDD_AudioGetInterruptType(void);

Return Values

An integer indicating the type of interrupt. The defined values are:

AUDIO_STATE_OUT_PLAYING
Sound is currently playing.
AUDIO_STATE_OUT_UNDERFLOW
Sound was playing but not enough data has been supplied to continue.
AUDIO_STATE_OUT_STOPPED
Playback is stopped.
AUDIO_STATE_IN_RECORDING
Sound is currently recording.
AUDIO_STATE_IN_OVERFLOW
Sound was recording but the reserve buffer was not processed in time before the DMA needed to write to it again.
AUDIO_STATE_IN_STOPPED
Recording is stopped.
AUDIO_STATE_IGNORE
The interrupt does not represent a state change or update and should be ignored by the MDD. This state can be used to report a PDD private interrupt. For example, initializing a CODEC may generate an interrupt that need not be reported.
AUDIO_STATE_OUT_MASK
Bitmask for the output state (0xF0).
AUDIO_STATE_IN_MASK
Bitmask for the input state (0x0F).

Remarks

This function supports the implementation of the audio PDD.

The PDD reports the status of the playback or record circuitry. The interrupt occurs when the audio DMA passes a buffer boundary. See the AUDIO_STATE return values for the possible states that an interrupt can represent.

AUDIO_STATE is the state of the audio device. This value can represent a state change of either the input or the output circuit or both. The lower 4 bits represents the input status, and the upper 4 bits represents the output status; so if the current interrupt is for both input and output, the values can be combined using the OR operator. However, if the interrupt represents only one circuit, the other 4 bits should remain 0; otherwise, the MDD interprets this as a change or update in the circuit’s status.

This function is declared in the Waveddsi.h header file.


PDD_AudioInitialize

This function initializes the audio device for operation.

Syntax

BOOL PDD_AudioInitialize(DWORD dwIndex);

Parameters

dwIndex
The parameter passed to the function WAV_Init. This allows the PDD layer to get device configuration information from the driver's registry entry.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function performs any one-time initialization tasks for the audio driver. This can include allocating memory for device registers and any DMA buffer pages.

This function is declared in the Waveddsi.h header file.


PDD_AudioMessage

This function sends messages from user applications to the audio driver's PDD layer.

Syntax

DWORD PDD_AudioMessage(UINT uMsg, DWORD dwParam1,
DWORD dwParam2);

Parameters

uMsg
Specifies the message to send.
dwParam1
Specifies parameter 1.
dwParam2
Specifies parameter 2.

Return Values

Dependent on uMsg.

Remarks

Custom functions can be accessed through this function. It is ultimately called in response to the waveOutMessage and waveInMessage functions.

This function is declared in the Waveddsi.h header file.


PDD_AudioPowerHandler

This function is responsible for managing the audio hardware during POWER_UP and POWER_DOWN notifications.

Syntax

VOID PDD_AudioPowerHandler(BOOL power_down);

Parameters

power_down
TRUE indicates that the audio device is shut down. FALSE indicates that this is a power-up request.

Return Values

None.

Remarks

This function is declared in the Waveddsi.h header file.


PDD_WaveProc

This function sends messages to the audio driver's PDD layer.

Syntax

MMRESULT PDD_WaveProc(WAPI_INOUT apidir, DWORD dwCode, DWORD dwParam1, DWORD dwParam2);

Parameters

apidir
Specifies the direction of the API requested.
dwCode
Specifies the function to execute.
dwParam1
Specifies parameter 1.
dwParam2
Specifies parameter 2.

Return Values

MMRESULT dependent on dwCode. If dwCode and apidir indicate a function that is not supported, this function returns MMSYSERR_NOTSUPPORTED.

Remarks

This function is used to implement all the waveOut and waveIn functions at the PDD level.

This function is declared in the Waveddsi.h header file.

See Also

WPDM_CLOSE, WPDM_CONTINUE, WPDM_ENDOFDATA, WPDM_GETDEVCAPS, WPDM_GETVOLUME, WPDM_OPEN, WPDM_PAUSE, WPDM_RESTART, WPDM_SETVOLUME, WPDM_STANDBY, WPDM_START, WPDM_STOP


PopEntryList

This function removes an entry in a singly-linked, driver-managed list.

At a Glance

Header file: | Ntcompat.h
Windows CE versions: | 2.0 and later

Syntax

PSINGLE_LIST_ENTRY PopEntryList(
IN PSINGLE_LIST_ENTRY ListHead);

Parameters

ListHead
Pointer to the driver-allocated storage for the head of the list.

The ListHead of type LIST_ENTRY is singly linked. The ListHead must be initialized to NULL before entries can be pushed and popped.

Return Values

Returns a pointer to the last-pushed entry in last-in, first-out (LIFO) order or a NULL pointer if the list is currently empty.

Remarks

A driver that calls this function can be running at IRQL >= DISPATCH_LEVEL only if the caller-allocated storage for ListHead is resident and only if pointers to every list entry remain valid at IRQL >= DISPATCH_LEVEL, as well.

See Also

PushEntryList


PrinterClose

Closes a printer handle previously opened by a call to the PrinterOpen function.

Syntax

VOID WINAPI PrinterClose(HANDLE hPrint);

Parameters

hPrint
Handle to a printer obtained through an earlier call to the PrinterOpen function.


PrinterOpen

Opens a specified printer port and returns a handle to the printer.

Syntax

HANDLE WINAPI PrinterOpen(PWSTR sPort);

Parameters

sPort
Pointer to a string that exactly matches any one of the strings listed in the HKEY_LOCAL_MACHINE\Printers\Ports registry key.

Return Values

A handle to the printer indicates success.


PrinterSend

Sends a block of data to a printer.

Syntax

BOOL WINAPI PrinterSend(HANDLE hPrint, LPCVOID lpBuffer,
DWORD dwBytes);

Parameters

hPrint
Handle to the port opened by the PrinterOpen function.
lpBuffer
Pointer to the data buffer containing the rendered band prepared by the printer driver.
dwBytes
Specifies the number of bytes in the buffer.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function writes dwBytes of data stored at the location pointed to by the parameter lpBuffer to a printer previously opened through a call to the PrinterOpen function.


PushEntryList

This function pushes an entry into a singly-linked, driver-maintained list.

At a Glance

Header file: | Ntcompat.h
Windows CE versions: | 2.0 and later

Syntax

VOID PushEntryList(IN PSINGLE_LIST_ENTRY ListHead,
IN PSINGLE_LIST_ENTRY Entry);

Parameters

ListHead
Pointer to the driver-allocated storage for the head of the list.

The ListHead of type SINGLE_LIST_ENTRY is singly linked. It must be initialized to NULL before the initial entry is pushed.

Entry
Pointer to the driver-allocated storage for an entry in the list.

Remarks

A driver that calls this function can be running at IRQL >= DISPATCH_LEVEL only if the caller-allocated storage for ListHead is resident and only if pointers to every list entry remain valid at IRQL >= DISPATCH_LEVEL, as well.

See Also

PopEntryList


RegisterClientDriverID

This function is called to register a unique string to identify a client driver.

Syntax

BOOL RegisterClientDriverID(void);

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function is defined in the Mousedrv.cpp file.


RegisterClientSettings

This function is called to set up USB driver load settings.

Syntax

BOOL RegisterClientSettings(LPCWSTR szDriverLibFile,
LPCWSTR szUniqueDriverId, LPCWSTR szReserved, LPCUSB_DRIVER_SETTINGS lpDriverSettings);

Parameters

szDriverLibFile
[IN] Specifies the client driver DLL name.
szUniqueDriverId
[IN] Specifies a unique client driver identifier string.
szReserved
[IN] Reserved. Set to 0 to ensure compatibility with future versions of Windows CE.
lpDriverSettings
[IN] Pointer to a driver settings structure that specifies how the driver is to be loaded.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function is called by client drivers during their installation routine. It sets up appropriate registry keys, based on lpDriverSettings so that the driver is loaded whenever the device is attached.

This function is defined in the Mousedrv.cpp file.

See Also

USB_DRIVER_SETTINGS, UnRegisterClientSettings


RegisterDevice

This function registers a new device driver with the file system so that applications can access the driver’s special device file names.

Syntax

HANDLE RegisterDevice(LPCWSTR lpszType DWORD dwIndex LPCWSTR lpszLib, DWORD dwInfo)

Parameters

lpszType
Pointer to the driver’s device file name prefix, such as COM, DEV, or PGR. The prefix must be 3 characters long.
dwIndex
Specifies a device identifier index. The index must be a number from 0 through 9. For example, the index value for “COM2:” is 2.
lpszLib
Pointer to the device driver DLL’s file name.
dwInfo
Specifies instance information. This is passed to the XXX_Init function.

Return Values

A handle to a device indicates success. Zero indicates failure. This is passed to the following functions exported by the client driver: XXX_Deinit, XXX_Open, XXX_PowerUp, and XXX_PowerDown.

Stream interface drivers are initialized by a call to this function. For most stream interface drivers, the Device Manager calls this function on behalf of the driver. However, applications can load their own special-purpose stream interface drivers, in which case they also call this function to register the driver. The IpszLib parameter is used to open the device. The IpszType parameter is a three-character string that identifies the function entry points in the DLL so that multiple devices can exist in one DLL. The lpszLib parameter is the name of the DLL that contains the entry points. Finally, dwInfo is passed to the initialization routine. So, for example, if there are two serial ports on a device and Comm.dll is the DLL implementing the serial driver, it presents the following initialization calls:

h1 = RegisterDevice(L"COM", 1, L"comm.dll",0x3f8);

Remarks

The DeregisterDevice function is used if a device is removed from the system or is being shut down:

In the following code example, h1 is returned from a call to this function.

DeregisterDevice(h1);


RegisterNotificationRoutine

This function registers a callback for device notifications.

Syntax

BOOL RegisterNotificationRoutine(USB_HANDLE hDevice, LPDEVICE_NOTIFY_ROUTINE lpNotifyRoutine,
LPVOID lpvNotifyParameter);

Parameters

hDevice
[IN] Handle to a USB device.
lpNotifyRoutine
[IN] Pointer to the address of a notification callback.
lpvNotifyParameter
[IN] Pointer to the parameter to pass to lpNotifyRoutine.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

Currently, the only notification that a callback can be registered for is USB_CLOSE_DEVICE.

This function is defined in the Mousedrv.cpp file.

See Also

UnRegisterNotificationRoutine


ReleaseFrameLengthControl

This function releases exclusive access to USB frame-length control.

Syntax

BOOL ReleaseFrameLengthControl(USB_HANDLE hDevice);

Parameters

hDevice
[IN] Handle to a USB device.

Return Values

TRUE indicates success. FALSE indicates that the client has not previously obtained a frame length control.

Remarks

This function is defined in the Mousedrv.cpp file.

See Also

SetFrameLength, TakeFrameLengthControl


RemoveEntryList

This function resets the links for an entry from a doubly linked, driver-managed list.

At a Glance

Header file: | Ntcompat.h
Windows CE versions: | 2.0 and later

Syntax

VOID RemoveEntryList(IN PLIST_ENTRY Entry);

Parameters

Entry
Pointer to the entry.

Remarks

A driver that calls this function can be running at IRQL >= DISPATCH_LEVEL only if the caller-allocated storage for Entry is resident.

This function sets the forward and backward links for the entry to each other.

See Also

InitializeListHead, IsListEmpty, RemoveHeadList, RemoveTailList


RemoveHeadList

This function removes an entry from the head of a doubly-linked list.

At a Glance

Header file: | Ntcompat.h
Windows CE versions: | 2.0 and later

Syntax

PLIST_ENTRY RemoveHeadList(IN PLIST_ENTRY ListHead);

Parameters

ListHead
Pointer to the driver-allocated storage for the head of the list.

The ListHead of type LIST_ENTRY is doubly linked.

Return Values

Returns a pointer to the entry at the head of the list or a NULL pointer if the list is currently empty.

Remarks

A driver that calls this function can be running at IRQL >= DISPATCH_LEVEL only if the caller-allocated storage for ListHead is resident and only if pointers to every list entry remain valid at IRQL >= DISPATCH_LEVEL, as well.

See Also

InitializeListHead, IsListEmpty, RemoveTailList, RemoveEntryList


RemoveTailList

This function removes an entry from the tail of a doubly-linked list.

At a Glance

Header file: | Ntcompat.h
Windows CE versions: | 2.0 and later

Syntax

PLIST_ENTRY RemoveTailList(IN PLIST_ENTRY ListHead);

Parameters

ListHead
Pointer to the driver-allocated storage for the head of the list.

The ListHead of type LIST_ENTRY is doubly linked.

Remarks

A driver that calls this function can be running at IRQL >= DISPATCH_LEVEL only if the caller-allocated storage for ListHead is resident and only if pointers to every list entry remain valid at IRQL >= DISPATCH_LEVEL, as well.

See Also

InitializeListHead, IsListEmpty, RemoveHeadList, RemoveEntryList


ReportPrinterStatus

This function returns the status of a printer or printing operation that is in progress.

At a Glance

Header file: | Prnport.h
Component: |
Platforms: | H/PC, Palm-size PC
Windows CE versions: | 2.0 and later

Syntax

BOOL WINAPI ReportPrinterStatus(DWORD dwStatus,
LPCTSTR lpPortName, LPCTSTR lpPrinterName, LPARAM lparam);

Parameters

dwStatus
One of the following flags:
  • PRINTER_E_OFFLINE
  • PRINTER_E_NOPAPER
  • PRINTER_E_DEVICE_FAULT
  • PRINTER_E_TIMEOUT
  • PRINTER_E_PAPERJAM
  • PRINTER_N_JOB_COMPLETE
  • PRINTER_N_PRINTING
lpPortName
Pointer to the printer port.
lpPrinterName
Pointer to the printer name.
lparam
Specifies a 32-bit message parameter.

Remarks

This function uses a registry setting to determine printer time-out errors for IR and serial printing. The time-out default value is 45seconds. It can be changed using the HKEY_LOCAL_MACHINE\PrintSettings\TimeOut registry key.


ResetDefaultPipe

This function resets the default pipe to a USB device.

Syntax

BOOL ResetDefaultPipe(USB_HANDLE hDevice);

Parameters

hDevice
[IN] Handle to a USB device whose default pipe you want to reset.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function clears the halted state of the default pipe within the USB stack. This function is only available in USBD interface version 1.1 and later.

See Also

IsDefaultPipeHalted, GetUSBDVersion


ResetPipe

This function resets an open USB pipe.

Syntax

BOOL ResetPipe(USB_PIPE hPipe);

Parameters

hPipe
[IN] Handle to an open USB pipe.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This request clears the halted state of a pipe within the USB stack and resets the data toggle state of the endpoint to DATA0. It does not reset the stalled state of the endpoint on the device; the device driver must do this by sending the appropriate FEATURE request on the default pipe. To determine whether the endpoint is stalled on the device side, call the GetStatus function.

This function is defined in the Mousedrv.cpp file.

See Also

ClearFeature, GetStatus, IsPipeHalted


SetDescriptor

This function sends a SET_DESCRIPTOR request to a USB device.

Syntax

USB_TRANSFER SetDescriptor(USB_HANDLE hDevice, LPTRANSFER_NOTIFY_ROUTINE lpStartAddress,
LPVOID lpvNotifyParameter, DWORD dwFlags, UCHAR bType,
UCHAR bIndex, WORD wLanguage, WORD wLength, LPVOID lpvBuffer);

Parameters

hDevice
[IN] Handle to a USB device.
lpStartAddress
[IN] Pointer to the address of a callback routine, which may be NULL.
lpvNotifyParameter
[IN] Pointer to the parameter to pass to a callback routine.
dwFlags
[IN] Specifies USB_NO_WAIT, or 0
bType
[IN] Specifies the descriptor type; one of the values USB_DEVICE_DESCRIPTOR_TYPE, USB_CONFIGURATION_DESCRIPTOR_TYPE, USB_STRING_DESCRIPTOR_TYPE, or a vendor specific value.
bIndex
[IN] Specifies an index within the descriptor.
wLanguage
[IN] Specifies the language identifier for string descriptors; 0 for others.
wLength
[IN] Specifies the descriptor length.
lpvBuffer
[IN] Specifies the buffer for descriptor data.

Return Values

A USB_TRANSFER handle indicates success. NULL indicates failure.

Remarks

This function initiates a control transfer to a USB device, which sets device descriptor information.

This function is defined in the Mousedrv.cpp file.

See Also

AbortTransfer, GetDescriptor, GetTransferStatus, IsTransferComplete


SetFeature

This function sends a SET_FEATURE request to a USB device.

Syntax

USB_TRANSFER SetFeature(USB_HANDLE hDevice, LPTRANSFER_NOTIFY_ROUTINE lpStartAddress,
LPVOID lpvNotifyParameter, DWORD dwFlags, WORD wFeature,
UCHAR bIndex);

Parameters

hDevice
[IN] Handle to a USB device.
lpStartAddress
[IN] Pointer to the address, which may be NULL, of a callback routine.
lpvNotifyParameter
[IN] Pointer to the parameter to pass to a callback routine.
dwFlags
[IN] Specifies USB_NO_WAIT or 0, plus one of the following:
USB_SEND_TO_DEVICE
Request for device.
USB_SEND_TO_INTERFACE
Request for interface.
USB_SEND_TO_ENDPOINT
Request for endpoint (default).
wFeature
[IN] Specifies one of the USB_FEATURE_* values, declared in the USB 100.h header file.
bIndex
[IN] Specifies 0 for DEVICE, or interface/endpoint number.

Return Values

A USB_TRANSFER handle indicates success. NULL indicates failure.

Remarks

This function initiates a control transfer to a USB device, requesting that a specified feature be enabled.

This function is defined in the Mousedrv.cpp file.

See Also

AbortTransfer, ClearFeature, GetTransferStatus, IsTransferComplete


SetFrameLength

This function changes the USB frame length.

Syntax

BOOL SetFrameLength(USB_HANDLE hDevice, HANDLE hEvent, USHORT uFrameLength);

Parameters

hDevice
[IN] Handle to a USB device.
hEvent
[IN] Handle to an event to signal when the frame length reaches target value.
uFrameLength
[IN] Specifies the desired frame length.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function should be used infrequently by client drivers because changing the USB frame length may affect other devices on the bus. The driver must obtain frame-control access by calling the TakeFrameLengthControl function before attempting to change the frame length. To enable devices to adjust to the new frame length, USB requires that frame-length changes be done gradually, over a period of frames, instead of abruptly jumping to the target frame length. The client driver passes in an event handle, which is signaled once the frame length has reached the target.

This function does not always set exactly the requested length.

This function is defined in the Mousedrv.cpp file.

See Also

ReleaseFrameLengthControl, TakeFrameLengthControl


SetInterface

This function sends a SET_INTERFACE request to a USB device, to change the device’s settings.

Syntax

USB_TRANSFER SetInterface(USB_HANDLE hDevice, LPTRANSFER_NOTIFY_ROUTINE lpStartAddress,
LPVOID lpvNotifyParameter, DWORD dwFlags, UCHAR bInterfaceNumber, UCHAR bAlternateSetting);

Parameters

hDevice
[IN] Handle to a USB device.
lpStartAddress
[IN] Pointer to the address of a callback routine, which should be NULL unless the USB_NO_WAIT flag is set.
lpvNotifyParameter
[IN] Pointer to the parameter to pass to the callback routine.
dwFlags
[IN] Specifies either of the values USB_NO_WAIT or 0.
bInterfaceNumber
[IN] Specifies the interface number being changed on the device.
bAlternateSetting
[IN] Specifies the number of the alternate.

Return Values

A USB_TRANSFER handle indicates success. NULL indicates failure.

Remarks

This function initiates a control transfer to a USB device, specifying the alternate setting to use for the specified interface.

This function is defined in the Mousedrv.cpp file.

See Also

AbortTransfer, GetInterface, GetTransferStatus, IsTransferComplete


SyncFrame

This function sends a SYNC_FRAME request to a USB device.

Syntax

USB_TRANSFER SyncFrame(USB_HANDLE hDevice, LPTRANSFER_NOTIFY_ROUTINE lpStartAddress,
LPVOID lpvNotifyParameter, DWORD dwFlags, UCHAR bEndpoint, LPWORD lpwFrame);

Parameters

hDevice
[IN] Handle to a USB device.
lpStartAddress
[IN] Pointer to the address, which may be NULL, of a callback routine.
lpvNotifyParameter
[IN] Pointer to the parameter to pass to a callback routine.
dwFlags
[IN] Specifies either of the values USB_NO_WAIT or 0.
bEndpoint
[IN] Specifies the endpoint number.
lpwFrame
[OUT] Specifies the frame number.

Return Values

A USB_TRANSFER handle indicates success. NULL indicates failure.

Remarks

This function initiates a control transfer to a USB device, requesting that the device send a synchronization frame. Isochronous endpoints use synchronization frames to synchronize a data stream.

This function is defined in the Mousedrv.cpp file.

See Also

AbortTransfer, GetTransferStatus, IsTransferComplete


TakeFrameLengthControl

This function registers for exclusive access to control the USB frame length.

Syntax

BOOL TakeFrameLengthControl(USB_HANDLE hDevice);

Parameters

hDevice
[IN] Handle to a USB device.

Return Values

TRUE indicates that the frame length control is specified. FALSE indicates that another driver has already obtained control of the USB frame length.

Remarks

Use with care. Changing the USB frame length may affect other devices on the bus.

This function is defined in the Mousedrv.cpp file.

See Also

ReleaseFrameLengthControl, SetFrameLength


TouchPanelCalibrateAPoint

This function converts non-calibrated points to calibrated points.

Syntax

VOID TouchPanelCalibrateAPoint(INT32 UncalX, INT32 UncalY,
INT32 *pCalX, INT32 *pCalY);

Parameters

UncalX
Specifies a non-calibrated x-coordinate.
UncalY
Specifies a non-calibrated y-coordinate.
pCalX
Pointer to the returned calibrated x-coordinate.
pCalY
Pointer to the returned calibrated y-coordinate.

Remarks

A factor of 4 is hidden in the calculations of x and y. This provides sub-pixel accuracy to the GWES, which theoretically will improve accuracy if handwriting recognition is added to Windows CE. This value is not declared in a header file, so it agrees with the divisor used by the GWES in Touch.cpp.

The transform coefficients are already in vCalcParam.

This function is defined in the header file Tchddi.h file and is available in Windows CE version 1.0 and later.


TouchPanelDisable

This function disables the touch screen.

Syntax

BOOL TouchPanelDisable(void);

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

When this function returns, the touch screen no longer generates pen events. This function is defined in the header file Tchddi.h file and is available in Windows CE version 1.0 and later.


TouchPanelEnable

This function enables and re-enables the touch screen.

Syntax

BOOL TouchPanelEnable(void);

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

After this function returns, the touch screen generates pen events.

This function is defined in the header file Tchddi.h file and is available in Windows CE version 1.0 and later.


TouchPanelGetDeviceCaps

This function returns information about the capabilities of the touch screen.

Syntax

BOOL TouchPanelGetDeviceCaps(ULONG iIndex, LPVOID lpOutput);

Parameters

iIndex
Integer specifying the capability to query; one of the following:
DDI_TPDC_SAMPLERATE
Sample rate.
DDI_TPDC_CALIBRATIONPOINTS
Coordinates (x and y) used for calibration.
DDI_TPDC_CALIBRATIONDATA
Coordinates (x and y) used for calibration mapping.
DDI_TPDC_SAMPLERATE
Size of the digitizer screen (x, y).
lpOutput
Pointer to the memory location(s) where the queried information is placed. The format of the referenced memory depends on the setting of iIndex. If the value is 0, the number of words required for the output data is returned.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function is defined in the header file Tchddi.h file and is available in Windows CE version 1.0 and later.


TouchPanelPowerHandler

This function handles power-state change notifications.

Syntax

VOID TouchPanelPowerHandler(BOOL bOff);

Parameters

bOff
Boolean. TRUE indicates that the system is being turned off. FALSE indicates the system is being turned on.

Remarks

This function is called in a kernel context and should not make any system calls. As with all power-down handlers, this function cannot call functions in other DLLs, memory allocators, debugging-output functions, or do anything that could cause a page fault. If power is being shut off, it should save the device state in local storage only, set a flag indicating that power is being shut off, and exit. If power is being restored, it should restore the saved device state and clear the power-off flag.

This function is defined in the header file Tchddi.h file and is available in Windows CE version 1.0 and later.


TouchPanelReadCalibrationAbort

This function aborts the currently active call to the TouchPanelCalibrateAPoint function.

Syntax

VOID TouchPanelReadCalibrationAbort(void);

Return Values

TRUE indicates success. FALSE indicates that there is no active TouchPanelCalibrateAPoint call in progress.

Remarks

This function is defined in the header file Tchddi.h file and is available in Windows CE version 1.0 and later.


TouchPanelReadCalibrationPoint

This function initiates the process of getting a calibration point.

Syntax

VOID TouchPanelReadCalibrationPoint(LONG UcalX, LONG UcalY);

Parameters

UcalX
Specifies a non-calibrated x-coordinate under calibration.
UcalY
Specifies a non-calibrated y-coordinate under calibration.

Return Values

TRUE indicates success. FALSE indicates failure. For extended error information, see GetLastError.

Remarks

This function causes the device driver to forward the last valid x-coordinates and y-coordinates between the tip states of initial down and up to the calibration callback function. The tip state of the forwarded coordinates is reported as initial down.

This function is defined in the header file Tchddi.h file and is available in Windows CE version 1.0 and later.


TouchPanelSetCalibration

This function initializes calibration information in a global parameter vCalcParam, which is used to convert non-calibrated points to calibrated points by the TouchPanelCalibrateAPoint function.

Syntax

VOID TouchPanelSetCalibration(INT32 cCalibrationPoints,
INT32 *pScreenXBuffer, INT32 *pScreenYBuffer, INT32 *pUncalXBuffer, INT32 *pUncalYBuffer);

Parameters

cCalibrationPoints
Integer indicating the number of calibration points.
pScreenXBuffer
Specifies an array of screen x-coordinates displayed.
pScreenYBuffer
Specifies an array of screen y-coordinates displayed.
pUncalXBuffer
Specifies an array of x-coordinates collected.
pUncalYBuffer
Specifies an array of y-coordinates collected.

Remarks

This is the 2-D version of the transform. A simpler 1-D transform is in the MDD code. The preprocessor variable TWO_DIMENSIONAL_CALIBRATION can be used to select which transform to use.

The 2-D version is more complicated but more accurate because it does not assume independent x and y values.

This function is defined in the header file Tchddi.h file and is available in Windows CE version 1.0 and later.


TouchPanelSetMode

This function sets information about the model’s touch screen device.

Syntax

BOOL TouchPanelSetMode(ULONG iIndex, LPVOID lpInput);

Parameters

iIndex
Integer specifying the mode to set; one of the following:
DDI_TPSM_SAMPLERATE_HIGH
Set the sample rate to the high rate.
DDI_TPSM_SAMPLERATE_LOW
Set the sample rate to the low rate.
lpInput
Pointer to the memory location(s) where the update information resides. The format of the memory referenced depends on the mode.

Return Values

TRUE indicates success. FALSE indicates failure. Extended error information is available through GetLastError.

Remarks

This function is defined in the header file Tchddi.h file and is available in Windows CE version 1.0 and later.


TranslateStringDescr

This function translates a USB string descriptor into a null-terminated string.

Syntax

BOOL TranslateStringDescr(
LPCUSB_STRING_DESCRIPTOR lpStringDescr, LPWSTR szString, DWORD cchStringLength);

Parameters

lpStringDescr
[IN] Pointer to a USB string descriptor.
szString
[OUT] Specifies the buffer to receive string data.
cchStringLength
[IN] Specifies the size, in characters, of the string buffer.

Return Values

TRUE indicates that lpStringDescr points to a valid USB string descriptor.

Remarks

If the string being translated would overflow the supplied buffer, it is truncated.

This function is defined in the Mousedrv.cpp file.


UnRegisterClientSettings

This function deregisters USB device driver settings.

Syntax

BOOL UnRegisterClientSettings(LPCWSTR szUniqueDriverId,
LPCWSTR szReserved, LPCUSB_DRIVER_SETTINGS lpDriverSettings);

Parameters

szUniqueDriverId
[IN] Specifies the client driver DLL name.
szReserved
[IN] Reserved. Set to 0 to ensure compatibility with future versions of Windows CE.
lpDriverSettings
[IN] Pointer to a driver settings structure that must match the settings the client was registered with.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function is called by client drivers in their installation routine. It sets up appropriate registry keys, based on lpDriverSettings so that the driver is loaded whenever the device is attached.

This function is defined in the Mousedrv.cpp file.

See Also

USB_DRIVER_SETTINGS, RegisterClientSettings


UnRegisterNotificationRoutine

This function removes a device notification callback.

Syntax

BOOL UnRegisterNotificationRoutine(USB_HANDLE hDevice, LPDEVICE_NOTIFY_ROUTINE lpNotifyRoutine,
LPVOID lpvNotifyParameter);

Parameters

hDevice
[IN] Handle to a USB device.
lpNotifyRoutine
[IN] Pointer to the address of a notification callback.
lpvNotifyParameter
[IN] Must be the same as the address passed to the RegisterNotificationRoutine function.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function is defined in the Mousedrv.cpp file.

See Also

RegisterNotificationRoutine


USBDeviceAttach

This function is a USB device attach routine.

Syntax

BOOL USBDeviceAttach(USB_HANDLE hDevice,
LPCUSB_FUNCS lpUsbFuncs, LPCUSB_INTERFACE lpInterface, LPCWSTR szUniqueDriverId, LPBOOL fAcceptControl, LPCUSB_DRIVER_SETTINGS lpDriverSettings, DWORD dwUnused);

Parameters

hDevice
[IN] Handle to a USB device.
lpUsbFuncs
[IN] Pointer to a USBD interface function table.
lpInterface
[IN] Pointer to the USB_INTERFACE structure that contains interface information if a client is loaded as an interface driver. If a client is not loaded for a specific interface, this parameter is NULL, and the client can get interface information through the FindInterface function.
szUniqueDriverId
[IN] Specifies a client driver identifier string.
fAcceptControl
[OUT] Filled in with TRUE if the driver accepts control of the device, or FALSE if USBD should continue to try to load client drivers.
lpDriverSettings
[IN] Pointer to the USB_DRIVER_SETTINGS structure that indicates how the driver is loaded.
dwUnused
[IN] Reserved for use with future versions of USBD.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function is called by the USBD module when a device is attached and a matching registry key is found in the LoadClients registry key. The driver should determine whether it can control the device and must load drivers for any uncontrolled interfaces on the device.

This function is defined in the Mousedrv.cpp file.

See Also

FindInterface, LoadGenericInterfaceDriver


USBInstallDriver

This function installs a USB client driver.

Syntax

BOOL USBInstallDriver(LPCWSTR szDriverLibFile);

Parameters

szDriverLibFile
[IN] Specifies the driver DLL name.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function is called by the USBD module when an unrecognized device is attached to the USB and the user enters the client driver DLL name. It registers a unique client identifier string with the USBD module and sets up any client driver settings.

This function is defined in the Mousedrv.cpp file.

See Also

USBUnInstallDriver


USBUnInstallDriver

This function uninstalls a USB client driver.

Syntax

BOOL USBUnInstallDriver(void);

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

This function can be called by a client driver to deregister itself with USBD.

This function is defined in the Mousedrv.cpp file.

See Also

USBInstallDriver


WAV_Close

This function closes the WAV IO device.

Syntax

BOOL WAV_Close(DWORD dwOpenData);

Parameters

dwOpenData
Specifies a value returned from a call to the WAV_Open function.

Return Values

TRUE indicates success. FALSE indicates failure.


WAV_Deinit

This function de-initializes the WAV IO device.

Syntax

PVOID WAV_Deinit(DWORD dwData);

Parameters

dwData
Specifies a value returned from a call to the WAV_Init function.

Return Values

TRUE indicates success. FALSE indicates failure.


WAV_Init

This function initializes the WAV IO device.

Syntax

PVOID WAV_Init(DWORD dwInfo);

Parameters

dwInfo
Specifies information passed to the RegisterDevice function.

Return Values

Returns a DWORD which is passed to the Wav_Open and Wav_ Deinit functions. NULL indicates failure.


WAV_IOControl

This function is the Device I/O control routine for the WAV IO device.

Syntax

BOOL WAV_IOControl(DWORD dwOpenData, DWORD dwCode,
PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut);

Parameters

dwOpenData
Specifies a value returned from a call to the WAV_Open function.
dwCode
Specifies an I/O control code for this function to be performed. This function supports only one I/OCTL value, IOCTL_WAV_MESSAGE.
pBufIn
Pointer to the MMDRV_MESSAGE_PARAMS input parameter structure.
dwLenIn
Specifies the size, in bytes, of input parameter structure (sizeof(MMDRV_MESSAGE_PARAMS)).
pBufOut
Pointer to the return value (DWORD).
dwLenOut
Specifies the size of the return value variable (sizeof(DWORD)).
pdwActualOut
Not used.

Return Values

TRUE indicates success. FALSE indicates failure.


WAV_Open

This function opens the WAV I/O device.

Syntax

PVOID WAV_Open(DWORD dwData, DWORD dwAccess,
DWORD dwShareMode);

Parameters

dwData
The function is free to use or ignore this parameter.
dwAccess
The function is free to use or ignore this parameter.
dwShareMode
The function is free to use or ignore this parameter.

Return Values

Returns a DWORD that is passed to the functions Wav_Read, Wav_Write, and so on. NULL indicates failure.


WAV_PowerDown

This function turns off the WAV I/O device.

Syntax

void WAV_PowerDown(void);

Remarks

This function is called to notify the WAV I/O device that the system is entering suspend mode. As with all power-down handlers, this function cannot call functions in other DLLs, memory allocators, debugging-output functions, or do anything that could cause a page fault.


WAV_PowerUp

This function notifies the WAV IO device that the system is leaving the suspend state.

Syntax

void WAV_PowerUp(void);

Remarks

This function is called to notify the WAV IO device that the system is leaving suspend mode.


WAV_Read

This function is the read routine for the WAV I/O device driver.

Syntax

DWORD WAV_Read(DWORD dwOpenData, LPVOID pBuf, DWORD len);

Parameters

dwOpenData
The function is free to use or ignore this parameter.
pBuf
The function is free to use or ignore this parameter.
len
The function is free to use or ignore this parameter.

Return Values

The Wave API Manager never calls the WAV_Read function, so this function can be empty and can have an arbitrary return value. WAV_Read is a required stream interface driver function, but the function WAV_IOControl handles all data communication. The audio MDD implementation always returns 0.


WAV_Seek

This function is the seek routine for the WAV I/O device.

Syntax

DWORD WAV_Seek(DWORD dwOpenData, long pos, DWORD type);

Parameters

dwOpenData
The function is free to use or ignore this parameter.
pos
The function is free to use or ignore this parameter.
type
The function is free to use or ignore this parameter.

Return Values

The Wave API Manager never calls the WAV_Seek function, so this routine can be empty and can have an arbitrary return value. WAV_Seek is a required stream interface driver function, but the function WAV_IOControl handles all data communication. The audio MDD implementation always returns –1.


WAV_Write

This function is the write routine for the WAV I/O device.

Syntax

DWORD WAV_Write(DWORD dwOpenData, LPCVOID pBuf, DWORD len);

Parameters

dwOpenData
The function is free to use or ignore this parameter.
pBuf
The function is free to use or ignore this parameter.
len
The function is free to use or ignore this parameter.

Return Values

The Wave API Manager never calls the WAV_Write function, so this routine may be empty and have an arbitrary return value. WAV_Write is a required stream interface driver function, but the function WAV_IOControl handles all data communication. The audio MDD implementation always returns 0.

Remarks

This function is defined in the Wav.c file.


XXX_Close

This function closes the device context identified by hOpenContext.

Syntax

BOOL XXX_Close(DWORD hOpenContext);

Parameters

hOpenContext
Handle returned by the XXX_Open function, used to identify the open context of the device.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

An application calls CloseHandle(hFile) to stop using a stream interface driver. The hFile parameter specifies the handle associated with the device context. In response to CloseHandle, the operating system invokes this function.

The file handle specified for hOpenContext is no longer valid after this function returns; if an application tries to perform stream I/O operations on that handle after calling CloseHandle, those operations fail.


XXX_Deinit

This function is called by the Device Manager to de-initialize a device.

Syntax

BOOL XXX_Deinit(DWORD hDeviceContext);

Parameters

hDeviceContext
Handle to the device context. The XXX_Init function creates and returns this identifier.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

When the user stops using a device, such as when a PC Card is removed from its socket, the Device Manager calls this function. This function is not called by applications. The Device Manager calls a driver’s XXX_Deinit function as a result of a call to the DeregisterDevice function. Your stream interface driver should free any resources it has allocated and terminate.


XXX_Init

This function is called by the Device Manager to initialize a device.

Syntax

DWORD XXX_Init(DWORD dwContext);

Parameters

dwContext
Specifies a pointer to a string containing the registry path to the active key for the stream interface driver.

Return Values

Returns a handle to the device context created. This handle is passed to the XXX_Open, XXX_PowerDown, XXX_PowerUp, and XXX_Deinit functions.

Remarks

The Device Manager calls this function as a result of a call to the RegisterDevice function. When the user starts using a device, such as when a PC Card is inserted, the Device Manager calls this function to initialize the device. This function is not called by applications.

The Device Manager specifies a pointer to a string containing the registry path to the active key of the specific PC Card device in the dwContext parameter. Usually, the string contains the registry path to a numbered subkey of the HKEY_LOCAL_MACHINE\Drivers\Active key. Your initialization function uses this information to access data stored in the registry.

This function might perform the following tasks:

  • Initialize the installed device to a default state.
  • Allocate resources used globally by the device driver.
  • Register a status callback function with Card Services. When the status of the device changes, the operating system calls this status callback function. For example, the status of a PC Card changes when you insert it or remove it.
  • Map system memory and I/O space to a PC Card device’s memory and I/O space.
  • Request notification on specific callback events.
  • For an interrupt-driven device, register an interrupt callback function. When the device generates an interrupt, the operating system calls this interrupt callback function.

After this function returns, the Device Manager checks the registry for a key named Ioctl for the driver, and if such a key is present the Device Manager calls XXX_IOControl, passing the value specified by Ioctl as the dwCode parameter. Your driver can use this function to finish initializing itself after it has been installed. For example, a driver might load additional modules that require the underlying driver to be installed before they can load.


XXX_IOControl

This function sends a command to a device.

Syntax

BOOL XXX_IOControl(
DWORD hOpenContext DWORD dwCode PBYTE pBufIn DWORD dwLenIn PBYTE pBufOut DWORD dwLenOut PDWORD pdwActualOut);

Parameters

hOpenContext
Handle to the open context of the device. The XXX_Open function creates and returns this identifier.
dwCode
Specifies a value indicating the I/O control operation to perform. These codes are device-specific and are usually exposed to programmers by means of a header file.
pBufIn
Pointer to the buffer containing data to be transferred to the device.
dwLenIn
Specifies the number of bytes of data in the buffer specified for pBufIn.
pBufOut
Pointer to the buffer used to transfer the output data from the device.
dwLenOut
Specifies the maximum number of bytes in the buffer specified by pBufOut.
pdwActualOut
Pointer to the DWORD buffer that this function uses to return the actual number of bytes received from the device.

Return Values

TRUE indicates success. FALSE indicates failure.

Remarks

An application uses the DeviceIOControl function to specify an operation to be performed. The operating system, in turn, invokes this function. The dwCode parameter contains the input or output operation to be performed. I/O control codes usually are specific to each device driver and typically are exposed to programmers by means of a header file.

If the Ioctl registry key is defined for your device driver, the Device Manager calls this function directly after it calls the XXX_Init function. It uses the value stored in the registry for the dwCode parameter and NULL for the pBufIn and pBufOut parameters. Your device might use this option to load other modules that require the installation of the basic device driver.


XXX_Open

This function opens a device for reading and/or writing. An application indirectly invokes this function when it calls CreateFile to open special device file names.

Syntax

DWORD XXX_Open(DWORD hDeviceContext DWORD AccessCode DWORD ShareMode);

Parameters

hDeviceContext
Handle to the device context. The XXX_Init function creates and returns this handle.
AccessCode
Specifies the requested access code of the device. The access is a combination of read and write.
ShareMode
Specifies the requested file share mode of the PC Card device. The share mode is a combination of file read and write sharing.

Return Values

This function returns a handle that identifies the open context of the device to the calling application. If your device can be opened multiple times, use this handle to identify each open context. This identifier is passed into the XXX_Read, XXX_Write, XXX_Seek, and XXX_IOControl functions. If the device cannot be opened, this function returns NULL.

Remarks

When this function is called, your device should allocate the resources that it needs for each open context and prepare for operation. This might involve preparing the device for reading or writing and initializing data structures it uses for operation.


XXX_PowerDown

This function suspends power to the device. It is useful only with devices that can be shut off under software control. Such devices are typically, but not exclusively, PC Card devices.

Syntax

void XXX_PowerDown(DWORD hDeviceContext);

Parameters

Handle
Handle to the device context. The call to the XXX_Init function returns this identifier.

Return Values

None.

Remarks

The operating system invokes this function to suspend power to the device. The operating system might call this function when it is about to enter the power-save mode. This function should not call any functions that might cause it to block, and it should return as quickly as possible. One strategy for returning quickly is to have this function set a global variable to indicate that a power loss occurred and to defer any complicated processing until later, when the driver’s XXX_PowerUp function is called.


XXX_PowerUp

This function restores power to a device.

Syntax

void XXX_PowerUp(DWORD hDeviceContext);

Parameters

hDeviceContext
Handle to the device context. The call to the XXX_Init function returns this identifier.

Return Values

None.

Remarks

The operating system invokes this function to restore power to a device. The operating system might call this function as it is leaving its power-save mode. This function should not call any functions that may cause it to block, and it should return as quickly as possible. This function should set a global variable to indicate that power was restored and perform any necessary processing later.

Some Windows CE–based platforms provide a subset of the specifications for PC Card power. If you are writing a driver for a PC Card device, consult the platform’s manufacturer to ensure that it can support your PC Card.


XXX_Read

This function reads data from the device identified by the open context.

Syntax

DWORD XXX_Read(DWORD hOpenContext, LPVOID pBuffer,
DWORD Count);

Parameters

hOpenContext
Handle to the open context of the device. The XXX_Open function creates and returns this identifier.
pBuffer
Pointer to the buffer which stores the data read from the device. This buffer should be at least Count bytes long.
Count
Specifies the number of bytes to read from the device into pBuffer.

Return Values

Returns 0 for the end-of-file, –1 for an error, or the number of bytes read for success.

Remarks

An application calls the ReadFile function to read from the device. The operating system, in turn, invokes this function. The hFile parameter is a handle to your device. The pData parameter points to the buffer that contains the data read from the device. The Size parameter indicates the number of bytes that the application wants to read from the device. The pSizeRead parameter is a pointer to a value where this function can store the number of bytes actually read from the device. The value returned from this function is equal to the value contained in pSizeRead, unless this function returns -1 for an error. If this function returns an error, pSizeRead contains 0.


XXX_Seek

This function moves the data pointer in the device.

Syntax

DWORD XXX_Seek(DWORD hOpenContext long Amount WORD Type);

Parameters

hOpenContext
Amount
Specifies the number of bytes to move the data pointer in the device. A positive value moves the data pointer toward the end of the file, and a negative value moves it toward the beginning.
Type
Specifies the starting point for the data pointer:
FILE_BEGIN
Indicates that the starting point is 0 or the beginning of the file.
FILE_CURRENT
Indicates that the current value of the file pointer is the starting point.
FILE_END
Indicates that the current end-of-file position is the starting point.

Return Values

The device’s new data pointer indicates success. A value of –1 indicates failure.

Remarks

An application calls the SetFilePointer function to move the data pointer in the device. The operating system, in turn, invokes this function. If your device is capable of being opened multiple times, this function modifies only the data pointer for the instance specified by hOpenContext.


XXX_Write

This function writes data to the device.

Syntax

DWORD XXX_Write(DWORD hOpenContext LPCVOID pSourceBytes DWORD NumberOfBytes);

Parameters

hOpenContext
Handle to the open context of the device. The call to the XXX_Open function returns this identifier.
pSourceBytes
Pointer to the buffer that contains the data to write.
NumberOfBytes
Specifies the number of bytes to write from the pSourceBytes buffer into the device.

Return Values

The number of bytes written indicates success. A value of –1 indicates failure.

Remarks

An application uses the WriteFile function to write to the device. The operating system, in turn, invokes this function.


Structures and Data Types

Along with the device drivers that Microsoft has defined for Windows CE, there are a number of C language structures that those drivers use. This section lists each structure, the fields it contains, and the meanings of those fields.


ACMDRV_MESSAGE_PARAMS

This structure contains members passed to the ACM_IOControl function.

Syntax

typedef struct {
DWORD dwDriverID;
HANDLE hDriver;
UINT uMsg;
LPARAM lParam1;
LPARAM lParam2;
} CMDRV_MESSAGE_PARAMS;

Members

dwDriverID
Specifies an instance identifier. This value is message-specific.
hDriver
Handle to a driver.
uMsg
Specifies one of the ACM driver messages.
lParam1
Specifies the first message member. Dependent on message type.
lParam2
Specifies the second message member. Dependent on message type.


ACMDRVFORMATSUGGEST

This structure contains client-specified input arguments to the AcmFormatSuggest function. The ACM fills in this structure with the client’s input arguments and passes it to an ACM driver with an ACMDM_FORMAT_SUGGEST message.

Syntax

typedef struct {
DWORD cbStruct;
DWORD fdwSuggest;
LPWAVEFORMATEX pwfxSrc;
DWORD cbwfxSrc;
LPWAVEFORMATEX pwfxDst;
DWORD cbwfxDst;
} ACMDRVFORMATSUGGEST;

Members

cbStruct
Specifies the size, in bytes, of the ACMDRVFORMATSUGGEST structure.
fdwSuggest
Contains restriction flags that limit the possible destination formats; any combination of the following flags:
ACM_FORMATSUGGESTF_WFORMATTAG
The wFormatTag member of the WAVEFORMATEX structure pointed to by pwfxDst contains a format tag. The driver can only suggest a destination format associated with the specified format tag; it cannot enforce the suggested format.
ACM_FORMATSUGGESTF_NCHANNELS
The nChannels member of the WAVEFORMATEX structure pointed to by pwfxDst contains a channel value. The driver can only suggest a destination format whose channel value matches the specified value; it cannot enforce the suggested format.
ACM_FORMATSUGGESTF_NSAMPLESPERSEC
The nSamplesPerSec member of the WAVEFORMATEX structure pointed to by pwfxDst contains a sample rate. The driver can only suggest a destination format whose sample rate matches the specified rate; it cannot enforce the suggested format.
ACM_FORMATSUGGESTF_WBITSPERSAMPLE
The nBitsPerSample member of the WAVEFORMATEX structure pointed to by pwfxDst contains a sample size. The driver can only suggest a destination format whose sample size matches the specified size; it cannot enforce the suggested format.
pwfxSrc
Pointer to a WAVEFORMATEX structure describing the source format.
cbwfxSrc
Specifies the size, in bytes, of the WAVEFORMATEX structure pointed to by pwfxSrc.
pwfxDst
Pointer to a WAVEFORMATEX structure to receive the suggested destination format description. If flags in the fdwSuggest member are set, corresponding members of this structure contain client-specified values. The driver should fill in all empty structure members.
cbwfxDst
Specifies the size, in bytes, of the WAVEFORMATEX structure pointed to by pwfxDst. The driver cannot return an extended WAVEFORMATEX structure that is larger than this size.

Remarks

The WAVEFORMATEX structures specified for source or destination formats might be extended structures defined for particular formats. For example, see IMAADPCMWAVEFORMAT in the Mmreg.h header file. Check the structure’s wFormatTag member to determine the format type and, therefore, the specific structure being passed.

This structure is declared in the Msacmdrv.h header file.


ACMDRVOPENDESC

This structure is used by the ACM for passing information to an ACM driver after the ACM sends the driver an ACM_Open function.

Syntax

typedef struct {
DWORD cbStruct;
FOURCC fccType;
FOURCC fccComp;
DWORD dwVersion;
DWORD dwFlags;
DWORD dwError;
LPCSTR pszSectionName;
LPCSTR pszAliasName;
DWORD dnDevNode;
} ACMDRVOPENDESC;

Members

cbStruct
Specifies the size, in bytes, of the structure.
fccType
Contains a four-character code identifying the driver type. The driver must compare this value with ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC, which is declared in the Msacm.h header file, to equal the string “audc”. If the member contents do not match this string, the driver must fail the open request by specifying an ACM_IOControl return value of 0.
fccComp
Not used. Defined to contain a four-character code identifying the driver sub-type.
dwVersion
Specifies the ACM’s version number. The version number format is 0xAABBCCCC, where AA is the major version number, BB is the minor version number, and CCCC is the build number. This value is also returned by the ACM’s acmGetVersion function.
dwFlags
No flags currently are defined. This member is identical to the fdwOpen argument passed to the acmDriverOpen function.
dwError
Specifies an error value. Drivers are restricted to specifying an ACM_IOControl return value of 0 for all error types. To provide better error resolution, ACM drivers can specify an error value in this member if they set the ACM_IOControl function’s return value to 0. The error value can be one of the MMSYSERR error values declared in the Mmsystem.h header file or one of the ACMERR error values declared in the Msacm.h header file.
pszSectionName
Pointer to the registry key under which the driver’s alias is stored. For more information, see the Windows NT Device Driver Kit.
pszAliasName
Pointer to the driver’s alias. This is the driver’s Msacm. alias entry in the registry. For more information, see the Windows NT Device Driver Kit.
dnDevNode
Specifies a device node identifier.

Remarks

When the ACM calls an ACM driver’s ACM_IOControl entry point and specifies a DRV_OPEN message, it includes an ACMDRVOPENDESC structure as the lParam2 member to ACM_IOControl. The ACM sends a DRV_OPEN message when an application calls the acmDriverOpen function.

This structure is declared in the Msacmdrv.h header file.


ACMDRVSTREAMHEADER

This structure describes a source buffer and a destination buffer associated with a conversion stream. This structure is used with the ACMDM_STREAM_PREPARE, ACMDM_STREAM_UNPREPARE, and ACMDM_STREAM_CONVERT messages.

Syntax

typedef struct {
DWORD cbStruct;
DWORD fdwStatus;
DWORD dwUser;
LPBYTE pbSrc;
DWORD cbSrcLength;
DWORD cbSrcLengthUsed;
DWORD dwSrcUser;
LPBYTE pbDst;
DWORD cbDstLength;
DWORD cbDstLengthUsed;
DWORD dwDstUser;
DWORD fdwConvert;
LPACMDRVSTREAMHEADER padshNext;
DWORD fdwDriver;
DWORD dwDriver;
DWORD fdwPrepared;
DWORD dwPrepared;
LPBYTE pbPreparedSrc;
DWORD cbPreparedSrcLength;
LPBYTE pbPreparedDst;
DWORD cbPreparedDstLength;
} ACMDRVSTREAMHEADER;

Members

cbStruct
Specifies the size, in bytes, of the structure.
fdwStatus
Contains status flags. The defined flags are as follows:
ACMSTREAMHEADER_STATUSF_DONE
Indicates that a conversion is complete. For synchronous conversion, the ACM sets this flag when the driver returns from an ACMDM_STREAM_CONVERT message. For asynchronous drivers, the driver sets this flag after the data has been converted. The ACM clears the flag before sending each ACMDM_STREAM_CONVERT message.
ACMSTREAMHEADER_STATUSF_PREPARED
Indicates that the data buffers have been prepared. This flag is set by the ACM, regardless of whether the driver or the ACM prepared the buffers. See ACMDM_STREAM_PREPARE and ACMDM_STREAM_UNPREPARE.
ACMSTREAMHEADER_STATUSF_INQUEUE
Used by the driver during asynchronous conversions to indicate that the structure has been queued for conversion. The driver is responsible for setting and clearing this flag. See ACMDM_STREAM_CONVERT.
dwUser
Specifies information supplied by a client for its own use.
pbSrc
Pointer to a source buffer. For an ACMDM_STREAM_CONVERT message, this buffer contains the data to be converted.
cbSrcLength
Specifies the length, in bytes, of the source buffer pointed to by pbSrc. For the ACMDM_STREAM_PREPARE and ACMDM_STREAM_UNPREPARE messages, this value represents the maximum source buffer size. For ACMDM_STREAM_CONVERT, this value represents the length of the data in the buffer.
cbSrcLengthUsed
Specifies the length, in bytes, of source data that has been converted. The driver sets this value to indicate the number of bytes in the source buffer that the driver actually converted. The value cannot be greater than the value in cbSrcLength.
dwSrcUser
Specifies information supplied by a client for its own use.
pbDst
Pointer to a destination buffer. For an ACMDM_STREAM_CONVERT message, the driver fills this buffer with converted data.
cbDstLength
Specifies the length, in bytes, of the destination buffer pointed to by pbDst.
cbDstLengthUsed
Specifies the length, in bytes, of destination data that has been converted. The driver sets this value to indicate the number of converted bytes that it has placed in the destination buffer. The value cannot be greater than the value in cbDstLength. If the conversion fails, the driver must set this value to 0.
dwDstUser
Specifies information supplied by a client for its own use.
fdwConvert
Specifies one of the following values:
ACMDM_STREAM_PREPARE
Not used.
ACMDM_STREAM_UNPREPARE
Not used.
ACMDM_STREAM_CONVERT
Specifies the acmStreamConvert function’s fdwConvert parameter.

For ACMDM_STREAM_CONVERT, the following flags are defined:

ACM_STREAMCONVERTF_BLOCKALIGN
Indicates that only whole blocks of source data should be converted. The size of a block is obtained from the source format’s WAVEFORMATEX structure. See ACMDRVSTREAMINSTANCE. If this flag is set, the driver should not convert extra bytes that do not make up a whole block. Generally, clients set this flag for all buffers in a conversion stream except the last one.
ACM_STREAMCONVERTF_START
Indicates that the driver re-initializes stream instance data—such as predictor coefficients or scale factors—to default starting values. This flag can be specified with the ACM_STREAMCONVERTF_END flag.
ACM_STREAMCONVERTF_END
Indicates that the driver returns end-of-stream data—such as tail end echo data for an echo filter—in the destination buffer along with data converted from the source buffer. This flag can be specified with the ACM_STREAMCONVERTF_START flag.
padshNext
Pointer to another ACMDRVSTREAMHEADER structure. An asynchronous driver can use this member for creating a queue of pending conversion requests. The ACM clears this member prior to sending an ACMDM_STREAM_PREPARE or ACMDM_STREAM_CONVERT message.
fdwDriver
Contains stream instance information supplied by the driver for its own use. This member is intended for storing driver-defined flags, but you can use it for storing any data that fits into a DWORD. The ACM clears this member prior to sending an ACMDM_STREAM_PREPARE message. Otherwise its value is preserved from one message to the next.
dwDriver
Specifies stream instance information supplied by the driver for its own use. You can use this member for any purpose. The ACM clears this member prior to sending an ACMDM_STREAM_PREPARE message. Otherwise, its value is preserved from one message to the next.
fdwPrepared
Specifies the fdwPrepared member to the acmStreamPrepareHeader function. Used by the ACM only.
dwPrepared
Specifies the parameter to the acmStreamPrepareHeader function. Used by the ACM only.
pbPreparedSrc
Pointer to the source buffer supplied with the acmStreamPrepareHeader function. Used by the ACM only.
cbPreparedSrcLength
Specifies the length of the source buffer supplied with the acmStreamPrepareHeader function. Used by the ACM only.
pbPreparedDst
Pointer to the destination buffer supplied with the acmStreamPrepareHeader function. Used by the ACM only.
cbPreparedDstLength
Specifies the length of the destination buffer supplied with the acmStreamPrepareHeader function. Used by the ACM only.

Remarks

This structure is declared in the Msacmdrv.h header file.


ACMDRVSTREAMINSTANCE

This structure describes an instance of a conversion stream.

Syntax

typedef struct {
DWORD cbStruct;
LPWAVEFORMATEX pwfxSrc;
LPWAVEFORMATEX pwfxDst;
LPWAVEFILTER pwfltr;
DWORD dwCallback;
DWORD dwInstance;
DWORD fdwOpen;
DWORD fdwDriver;
DWORD dwDriver;
HACMSTREAM has;
} ACMDRVSTREAMINSTANCE;

Members

cbStruct
Specifies the size, in bytes, of the ACMDRVSTREAMINSTANCE structure.
pwfxSrc
Pointer to a WAVEFORMATEX structure that defines the source format for a conversion stream.
pwfxDst
Pointer to a WAVEFORMATEX structure that defines the destination format for a conversion stream.
pwfltr
Pointer to an optional WAVEFILTER structure that defines a filter to be used on a conversion stream. This member is NULL if the application has not specified a filter.
dwCallback
Specifies the application-specified dwCallback parameter of the acmStreamOpen function.
dwInstance
Specifies the application-specified dwInstance parameter of the acmStreamOpen function.
fdwOpen
Specifies the application-specified dwOpen parameter of the acmStreamOpen function, which consists of a set of flags.
fdwDriver
Specifies driver-defined stream instance information. Although it is intended for storing flag values, an ACM driver can use this member to store any instance-specific DWORD value. Because the same ACMDRVSTREAMINSTANCE structure is passed with all stream messages associated with a particular stream instance, the stored value can be read or modified each time a stream message is received, and the last saved value is available the next time a stream message is received.
dwDriver
Specifies driver-defined stream instance information. An ACM driver can use this member for storing any instance-specific DWORD value, such as a pointer to a local, dynamically allocated structure. Because the same ACMDRVSTREAMINSTANCE structure is passed with all stream messages associated with a particular stream instance, the stored value can be read or modified each time a stream message is received, and the last saved value is available the next time a stream message is received.
has
Specifies the ACM-defined client handle to the open conversion stream.

Remarks

The ACM allocates this structure each time an application calls acmStreamOpen. This structure is then passed to the driver along with all stream messages associated with a particular stream instance. Information in this structure does not change, so if a driver validates information within this structure when it receives an ACMDM_STREAM_OPEN message, it does not have to validate the information again when it receives subsequent messages for the same stream instance.

This structure is declared in the Msacmdrv.h header file.


ACMDRVSTREAMSIZE

This structure contains information needed by an ACM driver to respond to an ACMDM_STREAM_SIZE message.

Syntax

typedef struct {
DWORD cbStruct;
DWORD fdwSize;
DWORD cbSrcLength;
DWORD cbDstLength;
} ACMDRVSTREAMSIZE;

Members

cbStruct
Specifies the size, in bytes, of the ACMDRVSTREAMSIZE structure.
fdwSize
One of the following flags, indicating the query type:
ACM_STREAMSIZEF_SOURCE
Indicates that the client has specified the size, in bytes, of a source buffer in the cbSrcLength member. The driver returns the required destination buffer length in cbDstLength.
ACM_STREAMSIZEF_DESTINATION
Indicates that the client has specified the size, in bytes, of a destination buffer in the cbDstLength member. The driver returns the required source buffer length in cbSrcLength.
cbSrcLength
Specifies the size, in bytes, of the source buffer. The flag value specified in fdwSize indicates whether this value is supplied by the client or by the driver.
cbDstLength
Specifies the size, in bytes, of the destination buffer. The flag value specified in fdwSize indicates whether this value is supplied by the client or by the driver.

Remarks

This structure is declared in the Msacmdrv.h header file.


BATTERY_STATUS

This structure specifies information about the power status of the system.

Syntax

typedef struct {
BYTE ACLineStatus;
BYTE BatteryFlag;
BYTE BatteryLifePercent;
BYTE Reserved1;
DWORD BatteryLifeTime;
DWORD BatteryFullLifeTime;
BYTE Reserved2;
BYTE BackupBatteryFlag;
BYTE BackupBatteryLifePercent;
BYTE fBatteriesChangedSinceLastCall;
DWORD BackupBatteryLifeTime;
DWORD BackupBatteryFullLifeTime;
} BATTERY_STATUS;

Members

ACLineStatus
Indicates whether the device is running on AC power; one of the following values:
AC_LINE_OFFLINE
Offline.
AC_LINE_ONLINE
Online.
AC_LINE_BACKUP_POWER
Backup power.
AC_LINE_UNKNOWN
Unknown status.

All other values are reserved.

BatteryFlag
Battery charge status; one of the following values:
BATTERY_FLAG_HIGH
High.
BATTERY_FLAG_LOW
Low.
BATTERY_FLAG_CRITICAL
Critical.
BATTERY_FLAG_CHARGING
Charging.
BATTERY_FLAG_NO_BATTERY
No system battery.
BATTERY_FLAG_UNKNOWN
Unknown status.

All other values are reserved.

BatteryLifePercent
Percentage of battery charge remaining. Must be in the range from 0 through 100 or BATTERY_PERCENTAGE_UNKNOWN.
Reserved1
Must be 0.
BatteryLifeTime
Number of seconds of battery life remaining or BATTERY_LIFE_UNKNOWN if remaining lifetime is unknown.
BatteryFullLifeTime
Number of seconds of battery life when at full charge or BATTERY_LIFE_UNKNOWN if full lifetime is unknown.
Reserved2
Must be 0.
BackupBatteryFlag
Backup battery charge status; one of the following values:
BATTERY_FLAG_HIGH
High.
BATTERY_FLAG_LOW
Low.
BATTERY_FLAG_CRITICAL
Critical.
BATTERY_FLAG_CHARGING
Charging.
BATTERY_FLAG_NO_BATTERY
No system battery.
BATTERY_FLAG_UNKNOWN
Unknown status.

All other values are reserved.

BackupBatteryLifePercent
Percentage of full backup battery charge remaining. Must be in the range from 0 through 100 or BATTERY_PERCENTAGE_UNKNOWN.
fBatteriesChangedSinceLastCall
One of the following values:
TRUE (1)
Indicates that the batteries have been changed since the last time BatteryDrvrGetStatus was called.
FALSE (0)
Indicates that the batteries have not been changed.

Usually, the driver determines this bit during an interrupt process. When a Battery Cover Opened interrupt occurs, the interrupt service routine (ISR) sets a global variable to indicate that the cover has been opened. The next time BatteryDrvrGetStatus is called, the driver sets fBatteriesChangedSinceLastCall to TRUE and resets variable. If the global variable was not set, fBatteriesChangedSinceLastCall is set to FALSE.

BackupBatteryLifeTime
Number of seconds of backup battery life remaining or BATTERY_LIFE_UNKNOWN if remaining lifetime is unknown.
BackupBatteryFullLifeTime
Number of seconds of backup battery life when at full charge or BATTERY_LIFE_UNKNOWN if full lifetime is unknown.

Remarks

This GWES data structure is implemented as part of porting native device drivers.

This structure is declared in the Battery.h header file.


CARD_CLIENT_HANDLE

This data type is a 32-bit value used to identify a driver. A successful call to the CardRegisterClient function returns a handle to the driver with this data type.

Syntax

typedef PVOID CARD_CLIENT_HANDLE;

Remarks

Most Card Services functions use this data type to identify the driver, including a call to CardDeregisterClient to remove the driver from Card Services.

See Also

CardDeregisterClient, CardRegisterClient


CARD_CONFIG_INFO

This structure contains PC Card configuration information. It is passed to the CardRequestConfiguration function. All members are input only.

Syntax

typedef struct {
CARD_SOCKET_HANDLE hSocket;
UINT16 fAttributes;
UINT8 fInterfaceType;
UINT8 uVcc; UINT8 uVpp1;
UINT8 uVpp2;
UINT8 fRegisters;
UINT8 uConfigReg;
UINT8 uStatusReg;
UINT8 uPinReg;
UINT8 uCopyReg;
UINT8 uExtendedStatus;
} CARD_CONFIG_INFO, *PCARD_CONFIG_INFO;

Members

hSocket
Handle to a socket and function pair.
fAttributes
Contains a bitmask for specifying interrupt request (IRQ), Direct Memory Access (DMA), and voltage options.
CFG_ATTR_IRQ_STEERING
Enables IRQ steering in the socket controller.
CFG_ATTR_ENABLE_DMA
Enables DMA.
fInterfaceType
Contains a bitmask specifying memory or I/O interface.
CFG_IFACE_MEMORY
Puts socket controller in memory-only interface mode.
CFG_IFACE_MEMORY_IO
Puts the socket controller in memory mode and I/O interface mode.
uVcc
Specifies the Vcc voltage to use, in 0.1 volt increments.
uVpp1
Specifies the Vpp1 voltage to use, in 0.1 volt increments.
uVpp2
Specifies the Vpp2 voltage to use, in 0.1 volt increments.
fRegisters
Specifies a bitmask indicating which registers are present. Each of these bits indicates the presence of one of the standard function and configuration registers in the attribute space of the PC Card. By calling CardRequestConfiguration, a driver can set these registers to whatever initial values the PC Card needs.
CFG_REGISTER_CONFIG
Indicates that the configuration option register (uConfigReg) contains data.
CFG_REGISTER_STATUS
Indicates that the function configuration and status register (uStatusReg) contains data.
CFG_REGISTER_PIN
Indicates that the pin replacement register (uPinReg) contains data.
CFG_REGISTER_COPY
Indicates that the socket and copy register (uCopyReg) contains data.
CFG_REGISTER_EXSTATUS
Indicates that the extended status register (uExtendedStatus) contains data.
uConfigReg
Specifies the initial bitmask value to write to a configuration option register.

The lower 6 bits of the configuration option register specify which configuration number to use for single function cards.

FCR_COR_LEVEL_IREQ
1 = level mode interrupts, 0 = pulse mode.
FCR_COR_SRESET
1 = soft reset.
uStatusReg
Specifies the initial value to write to a function status register. The following bitmask values are defined:
FCR_FCSR_INTR_ACK
Acknowledge interrupt.
FCR_FCSR_INTR
Interrupt pending.
FCR_FCSR_PWR_DOWN
Place PC Card in off mode.
FCR_FCSR_AUDIO
Enable audio signal on BVD2 (pin 62).
FCR_FCSR_IO_IS_8
Used by the host to indicate 8-bit-only I/O.
FCR_FCSR_STSCHG
Enable status change (STSCHG, pin 63) from PC Card.
FCR_FCSR_CHANGED
Specifies whether one of the status-changed bits is set in the pin replacement register.
uPinReg
Specifies the initial value to write to a pin replacement register.
uCopyReg
Specifies the initial value to write to a socket and copy register.
uExtendedStatus
Specifies the initial value to write to an extended status register.

Remarks

Card Services remembers the base address of the configuration registers, so there is no need for a uConfigBase member.

See Also

CardRequestConfiguration


CARD_DATA_PARMS

This structure contains tuple information passed to the CardGetTupleData function.

Syntax

typedef struct {
CARD_SOCKET_HANDLE hSocket;
UINT16 fAttributes;
UINT8 uDesiredTuple;
UINT8 uTupleOffset;
UINT16 fFlags;
UINT32 uLinkOffset;
UINT32 uCISOffset;
UINT16 uBufLen;
UINT16 uDataLen;
} CARD_DATA_PARMS, *PCARD_DATA_PARMS;

Members

hSocket
Handle to a socket and function pair.
fAttributes
[IN] Specify TUPLE_RETURN_LINKS to return link tuples. The first bit is 1.
uDesiredTuple
[IN] Specifies the desired tuple code. If it is 0xFF, the first tuple encountered is returned.
uTupleOffset
[IN] Specifies an offset into tuple data.
fFlags
[IN/OUT] Specifies flags used internally by Card Services. A driver must maintain this value between calls to tuple functions.
uLinkOffset
[IN/OUT] Specifies a tuple link offset used internally by Card Services. A driver must maintain this value between calls to tuple functions.
uCISOffset
[IN/OUT] Specifies CIS state information used internally by Card Services. A driver must maintain this value between calls to tuple functions.
uBufLen
[IN] Specifies the length, in maximum number of bytes, of tuple data.
uDataLen
[OUT] Specifies the length, in actual number of bytes, of tuple data.

Remarks

Because this structure is similar to the CARD_TUPLE_PARMS structure, a driver could use a single CARD_DATA_PARMS structure for all calls to the CardGetFirstTuple, CardGetNextTuple, and CardGetTupleData functions.

See Also

CARD_TUPLE_PARMS, CardGetFirstTuple, CardGetNextTuple, CardGetTupleData


CARD_EVENT

This type is used for event values in a registered driver callback function. Card Services calls the callback function when an associated PC Card event occurs.

Syntax

typedef UINT32 CARD_EVENT;

See Also

CardRegisterClient, CLIENT_CALLBACK


CARD_EVENT_MASK_PARMS

This structure contains event mask configurations passed to the CardGetEventMask and CardSetEventMask functions.

Syntax

typedef struct {
CARD_SOCKET_HANDLE hSocket;
UINT16 fAttributes;
UINT16 fEventMask;
} CARD_EVENT_MASK_PARMS, *PCARD_EVENT_MASK_PARMS;

Members

hSocket
Handle to a socket and function pair.
fAttributes
[IN] Specifies whether to return a global event mask or the event mask associated with the indicated socket and function pair. One of the following values:
0
Global event mask.
1
Specific event mask.
fEventMask
Specifies a bitmask of socket events. This member is input-only for CardSetEventMask and output-only for CardGetEventMask.

Remarks

This structure specifies global events or the events for a specified socket and function pair that a driver is interested in.

See Also

CardGetEventMask, CardSetEventMask


CARD_EVENT_PARMS

This structure contains additional information for particular callback events and is passed as the third member to the client’s callback function.

Syntax

typedef struct {
UINT32 uClientData;
UINT32 Parm1;
UINT32 Parm2;
} CARD_EVENT_PARMS, *PCARD_EVENT_PARMS;

Members

uClientData
Specifies context data specified by the CardRegisterClient function.
Parm1
Specifies an event-value member.

The following callback events require additional data passed to the client’s callback function:

CE_CARD_INSERTION
Points to the PC Card’s Plug and Play identifier string.
CE_REGISTRATION_COMPLETE
Specifies a driver handle of data type CARD_CLIENT_HANDLE.
CE_EXCLUSIVE_COMPLETE
Exclusive status.
CE_WRITE_PROTECT
Write-protect status.
Parm2
Specifies an event-value member.

The following callback events require additional data passed to the client’s callback function:

CE_CARD_INSERTION
Specifies a driver handle.
CE_REGISTRATION_COMPLETE
Not used.
CE_EXCLUSIVE_COMPLETE
Not used.
CE_WRITE_PROTECT
Not used.

Remarks

For all other callback events, the driver can safely ignore Parm1 and Parm2.

See Also

CardRegisterClient, CLIENT_CALLBACK


CARD_ISR

When a PC Card generates an interrupt on the PC Card interrupt line, Card Services calls the interrupt service function handler that is associated with a specified socket and function pair. Interrupt service function handlers must conform to the CARD_ISR prototype.

Syntax

typedef void
(*CARD_ISR)( UINT32 uISRContextData );

Members

uISRContextData
Contains context data specified by the CardRequestIRQ function that the driver can interpret as needed. This member usually is a pointer to a structure representing the state of the socket and function pair.

Remarks

When a PC Card generates an interrupt, Card Services first determines which function caused the interrupt, then calls the associated interrupt service function with the specified socket and function pair. For single function cards, the function number is 0.

A stream interface driver calls CardRequestIRQ to register an interrupt service routine for a specified socket and function pair. Card Services clears the interrupt condition in the card configuration registers when the interrupt callback function returns.

The interrupt callback function must clear the function interrupt request source on the PC Card and return as quickly as possible. If more time is required for processing the interrupt, the callback function should spawn a thread for further processing of the interrupt.

The interrupt service function handler is not a true kernel-mode interrupt service routine. Rather, it is a user-mode callback function that Card Services calls directly.

See Also

CARD_ISR, CardRequestIRQ, CardReleaseIRQ


CARD_REGISTER_PARMS

This structure contains driver characteristics passed to the CardRegisterClient function. All members are input-only.

Syntax

typedef struct {
UINT16 fAttributes;
UINT16 fEventMask;
UINT32 uClientData;
} CARD_REGISTER_PARMS, *PCARD_REGISTER_PARMS;

Members

fAttributes
A bitmask of the following flags:
CLIENT_ATTR_MEM_DRIVER
RAM or SRAM memory driver.
CLIENT_ATTR_MTD_DRIVER
Flash RAM memory driver, sometimes known as a Memory Technology driver.
CLIENT_ATTR_IO_DRIVER
I/O driver.
CLIENT_ATTR_NOTIFY_SHARED
Sharable PC Card.
CLIENT_ATTR_NOTIFY_EXCLUSIVE
Exclusively used PC Card.
fEventMask
Specifies a global socket events bitmask.
uClientData
Specifies 32 bits of context data sent to the client’s callback function. This data is typically a pointer to a data structure.

Remarks

The client data in uClientData is passed unchanged to the stream interface driver’s callback function. The client can interpret this context data in any manner it chooses.

See Also

CardRegisterClient, CLIENT_CALLBACK


CARD_SOCKET_HANDLE

This structure identifies a socket and function pair composed of a socket number and function number.

Syntax

typedef struct {
UINT8 uSocket;
UINT8 uFunction;
} CARD_SOCKET_HANDLE, *PCARD_SOCKET_HANDLE;

Members

uSocket
Specifies the socket number. The first socket is 0.
uFunction
Specifies the function number on the socket. The first function is 0.

Remarks

The stream interface driver generates these values and uses them in various Card Services functions.

For single function cards, the function number is 0. For multiple function cards, the function number ranges from 0 through 1 less than the number of functions on the card.


CARD_STATUS

This structure is used by the CardGetStatus function to return data.

Syntax

typedef struct {
CARD_SOCKET_HANDLE hSocket;
UINT16 fCardState;
UINT16 fSocketState;
} CARD_STATUS, *PCARD_STATUS;

Members

hSocket
Handle to a socket and function pair.
fCardState
[OUT] Specifies a bitmask indicating current card state.
fSocketState
[OUT] Specifies a bitmask indicating card state changes.

See Also

CardGetStatus


CARD_TUPLE_PARMS

This structure contains tuple information passed to the CardGetFirstTuple, CardGetNextTuple, and CardGetTupleData functions.

Syntax

typedef struct {
CARD_SOCKET_HANDLE hSocket;
UINT16 fAttributes;
UINT8 uDesiredTuple;
UINT8 uReserved;
UINT16 fFlags;
UINT32 uLinkOffset;
UINT32 uCISOffset;
UINT8 uTupleCode;
UINT8 uTupleLink;
} CARD_TUPLE_PARMS, *PCARD_TUPLE_PARMS;

Members

hSocket
Handle to a socket and function pair.
fAttributes
[IN] Specifies TUPLE_RETURN_LINKS to return link tuples. The first bit is one.
uDesiredTuple
[IN] Specifies the desired tuple code. If it is 0xFF, the first tuple encountered is returned.
uReserved
Reserved for internal use only to maintain alignment with the CARD_DATA_PARMS structure.
fFlags
[IN/OUT] Specifies flags used internally by Card Services. A driver must maintain this value between calls to tuple functions.
uLinkOffset
[IN/OUT] Specifies a tuple link offset used internally by Card Services. A driver must maintain this value between calls to tuple functions.
uCISOffset
[IN/OUT] Specifies CIS state information used internally by Card Services. A driver must maintain this value between calls to tuple functions.
uTupleCode
[OUT] Specifies the type of tuple found.
uTupleLink
[OUT] Specifies a link value for tuple found.

Remarks

A driver should maintain the values for the hSocket, fFlags, uLinkOffset, and uCISOffset members after using CardGetFirstTuple and between calls to CardGetNextTuple. Card Services requires these members to resume the tuple search.

See Also

CARD_DATA_PARMS, CardGetFirstTuple, CardGetNextTuple, CardGetTupleData


CARD_WINDOW_HANDLE

This data type is used by the CardRequestWindow function to map a window within system memory. The window can be used to access the PC Card memory or I/O space. The CardRequestWindow function returns a 32-bit handle to the mapped window with this data type.

Syntax

typedef PVOID CARD_WINDOW_HANDLE;

Remarks

You can use the handle for calls to the CardMapWindow and CardReleaseWindow functions.

See Also

CardMapWindow, CardReleaseWindow, CardRequestWindow


CARD_WINDOW_PARMS

This structure contains desired memory or I/O window characteristics passed to the CardRequestWindow function.

Syntax

typedef struct {
CARD_SOCKET_HANDLE hSocket;
UINT16 fAttributes;
UINT32 uWindowSize;
UINT8 fAccessSpeed;
} CARD_WINDOW_PARMS, *PCARD_WINDOW_PARMS;

Members

hSocket
Handle to a socket and function pair.
fAttributes
[IN] Specifies a bitmap for attributes for the memory or I/O window.
uWindowSize
[IN/OUT] Specifies, in bytes, the desired window size.
fAccessSpeed
[IN] Specifies a bit-encoded access speed characteristic for memory windows, or the number of I/O address lines for I/O windows.

See Also

CardRequestWindow


CLIENT_CALLBACK

This structure specifies the prototype for PC Card event callback functions. The Card Services driver calls the callback function to notify the stream interface device driver of a PC Card event.

Syntax

typedef STATUS (
*CLIENT_CALLBACK)
( CARD_EVENT CardEvent
CARD_SOCKET_HANDLE hSocket
PCARD_EVENT_PARMS pCardEventParms );

Members

CardEvent
Specifies one of the Card Services callback event values.
hSocket
Handle to a socket and function pair.
pCardEventParms
Pointer to the members associated with CardEvent.

Return Values

CERR_SUCCESS indicates success. One of the following indicates failure:

CERR_BAD_ARGS
Indicates that the pointer specified for pCardEventParms is invalid.
CERR_BAD_SOCKET
Indicates that the socket identifier specified for hSocket is invalid or that a PC Card is not inserted.

Remarks

When a PC Card event occurs, Card Services notifies drivers by calling their registered callback functions. The callback function must conform to the CLIENT_CALLBACK prototype.

Drivers can request notice for certain events when they register with the CardRegisterClient function.

You can use the CardRequestSocketMask and CardSetEventMask functions to request event notification for a specific socket and function pair.

See Also

CardRegisterClient, CardRequestSocketMask, CardSetEventMask


DEVICE_LIST

This structure stores information about each serial hardware device that can be handled by a particular serial device driver.

Syntax

typedef struct __DEVICE_LIST {
LPSTR DllName;
ULONG NumberOfDevices;
PHWOBJ *DeviceArray;
} DEVICE_LIST, *PDEVICE_LIST;

Members

DllName
Specifies the name of the DLL that contains the PDD layer associated with a serial device driver.
NumberOfDevices
Specifies the number of serial hardware devices that can be managed by the device driver named in DllName.
*DeviceArray
Specifies an array of HWOBJ structures that describes each serial hardware device.

Remarks

This structure is declared in the Serhw.h header file.

See Also

HWOBJ


HW_VTBL

This structure stores function pointers to the functions that serial port drivers must implement.

Syntax

typedef struct __HW_VTBL {
PVOID (*HWInit)(ULONG Identifier, PVOID pMDDContext, PHWOBJ pHWObj);
ULONG (*HWDeinit)(PVOID pHead);
BOOL (*HWOpen)(PVOID pHead);
ULONG (*HWClose)(PVOID pHead);
ULONG (*HWGetBytes)(PVOID pHead, PUCHAR pTarget,
PULONG pBytes);
PVOID (*HWGetRxStart)(PVOID pHead);
INTERRUPT_TYPE (*HWGetIntrType)(PVOID pHead);
VOID (*HWOtherIntrHandler)(PVOID pHead);
VOID (*HWLineIntrHandler)(PVOID pHead);
ULONG (*HWGetRxBufferSize)(PVOID pHead);
VOID (*HWTxIntrHandler)(PVOID pHead);
ULONG (*HWPutBytes)(PVOID pHead, PUCHAR pSrc,
ULONG NumBytes, PULONG pBytesSent);
BOOL (*HWPowerOff)(PVOID pHead);
BOOL (*HWPowerOn)(PVOID pHead);
VOID (*HWClearDTR)(PVOID pHead);
VOID (*HWSetDTR)(PVOID pHead);
VOID (*HWClearRTS)(PVOID pHead);
VOID (*HWSetRTS)(PVOID pHead);
BOOL (*HWEnableIR)(PVOID pHead, ULONG BaudRate);
BOOL (*HWDisableIR)(PVOID pHead);
VOID (*HWClearBreak)(PVOID pHead);
VOID (*HWSetBreak)(PVOID pHead);
BOOL (*HWXmitComChar)(PVOID pHead, UCHAR ComChar);
ULONG (*HWGetStatus)(PVOID pHead, LPCOMSTAT lpStat);
VOID (*HWReset)(PVOID pHead);
VOID (*HWGetModemStatus)(PVOID pHead, PULONG pModemStatus);
VOID (*HWGetCommProperties)(PVOID pHead,
LPCOMMPROP pCommProp);
VOID (*HWPurgeComm)(PVOID pHead, DWORD fdwAction);
BOOL (*HWSetDCB)(PVOID pHead, LPDCB pDCB);
BOOL (*HWSetCommTimeouts)(PVOID pHead,
LPCOMMTIMEOUTS lpCommTO);
BOOL (*HWIoctl)(PVOID pHead, DWORD dwCode,
PBYTE pBufIn,DWORD dwLenIn,
PBYTE pBufOut,DWORD dwLenOut,
PDWORD pdwActualOut);
} HW_VTBL, *PHW_VTBL;

Members

HWInit
A function which performs the required initialization for the serial port driver's PDD layer.
HWDeinit
A function which performs any required work when the driver is uninitialized, such as freeing allocated data structures.
HWOpen
A function that is called when an application opens a serial port. Typically this function is responsible for powering the serial port hardware and initializing its state, if it is not already open.
HWClose
A function that is called when an application closes a serial port. Typically this function is responsible for freeing any data allocated in HWOpen and removing power from serial port hardware.
HWGetBytes
A function that is called by the MDD layer to retrieve received characters from the UART when RX_INTR is returned from the function HWGetIntrType. The return value indicates number of received bytes, if any, that were dropped by the UART or the PDD.
HWGetRxStart
A function that returns the address of the start of the hardware receive buffer. This is subsequently passed to the function InterruptInitialize.
HWGetIntrType
This function is called by the MDD layer when an interrupt event is signaled. This function determines the cause of the interrupt and returns an interrupt mask composed of the possible types INTR_RX, INTR_TX, INTR_MODEM, INTR_LINE, or INTR_NONE.
HWOtherIntrHandler
This function is called by the MDD layer to handle an INTR_MODEM interrupt.
HWLineIntrHandler
This function is called by the MDD layer to handle an INTR_LINE interrupt.
HWGetRxBufferSize
This function returns the number of bytes which can be held in the receive buffer or FIFO.
HWTxIntrHandler
This function is called by the MDD layer to handle an INTR_TX interrupt.
HWPutBytes
This function is called by the MDD layer'ss COM_Write function to transmit data. It loads the FIFO and returns to the MDD. A non-zero return code indicates that the MDD must perform polling to detect changes in the flow control state. Hardware which supports interrupt generation when the line state changes should return 0. The return value indicates number of milliseconds to wait before polling.
HWPowerOff
This function is called as part of the system's power down sequence. This function may make no system calls, and should perform the minimum work required to save the serial port hardware's status.
HWPowerOn
This function is called as part of the system's power on sequence. It should use data saved in HWPowerOff to restore the state of the serial port hardware. This function may not make system calls.
HWClearDTR
This function clears the DTR signal.
HWSetDTR
This function sets the DTR signal.
HWClearRTS
This function clears the RTS line
HWSetRTS
This function sets the RTS line.
HWEnableIR
This function enables the IR interface for ports which support IR mode. Typically, this involves switching the UART outputs from a standard line driver to an IR LED interface.
HWDisableIR
This function disables IR mode on ports which support it.
HWClearBreak
This function clears the break condition on the TX line.
HWSetBreak
This function sets the break condition on the TX line. It is not supported by all UART chips.
HWXmitComChar
This function transmits the specified character ahead of any other data which may already have been queued by the HWPutBytes routine. Not supported by all hardware.
HWGetStatus
This function is called in response to the IOCTL_SERIAL_GET_COMMSTATUS I/O control code. It returns the serial port's current status. Note, this function must also clear the CommErrors field.
HWReset
This function resets the ComStatus structure used by HWGetStatus.
HWGetModemStatus
This function is called in response to the IOCTL_SERIAL_GET_MODEMSTATUS I/O control code. See the Win32 documentation for description of the ModemStatus structure.
HWGetCommProperties
This function fills in the CommProperties structure with information about the serial port's device capabilities.
HWPurgeComm
This function clears the UART data as indicated by the TX_CLEAR, RX_CLEAR, TX_ABORT, and RX_ABORT flags.
HWSetDCB
This function sets the port characteristics as indicated by the DCB structure passed as input to the function.
HWSetCommTimeouts
This function sets communications timeout values as indicated. Note, one of the primary tasks of the MDD layer is to handle communications timeouts. The PDD layer typically does not have to do anything in its implement of this function.
HWIoctl
This function candles any I/O control codes. In addition to the standard Win32 codes, any PDD layer may choose to implement additional codes specific to the underlying hardware capabilities.


HWOBJ

This structure describes the characteristics of serial hardware devices.

Syntax

typedef struct __HWOBJ {
PVOID pDeviceParent;
ULONG BindFlags;
DWORD dwIntID;
PVOID pReserved;
PHW_VTBL pFuncTbl;
} HWOBJ, *PHWOBJ;

Members

pDeviceParent
Pointer back to the DEVICE_LIST structure which refers to this HWOBJ in its DeviceArray member.
BindFlags
Flags controlling how the MDD layer behaves with respect to the driver’s interrupt service thread (IST):
THREAD_IN_PDD
The MDD layer does nothing; interrupt handling is done in the PDD layer.
THREAD_AT_INIT
The MDD starts the IST when the driver is initialized.
THREAD_AT_OPEN
Not supported.
dwIntID
Interrupt identifier—such as SYSINTR_SERIAL, SYSINTR_TOUCH, and so on—used with the THREAD_AT_INIT and THREAD_AT_OPEN flags,.
pReserved
Not used; set to NULL.
pFuncTbl
Pointer to an HW_VTBL structure that contains a table of function pointers for each of the serial device hardware functions, such as HWOpen, HWClearBreak, HWSetDTR, and so on. The HW_VTBL structure and the full list of functions are declared in the Serhw.h header file.

Remarks

This structure enables one serial driver MDD layer to use multiple PDD layers for hardware serial ports that have different physical behavior but identical logical behavior, such as an infrared serial port versus a standard 9-pin serial port.

This structure is declared in the Serhw.h header file.

See Also

DEVICE_LIST


MediaSpecificInformation

This structure contains information about the characteristics of the network hardware bound to a protocol.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

typedef struct MediaSpecificInformation {
 UINT NextEntryOffset;
NDIS_CLASS_ID ClassId;
UINT Size;
UCHAR ClassInformation[1];
} MEDIA_SPECIFIC_INFORMATION;

Members

NextEntryOffset
Specifies the byte offset to this member in the next record, if any. Zero indicates that this is the last record in the buffer; the values of all remaining members in the last record are also 0. The value of this member must be quad-aligned.
ClassId
Specifies the type of the record. Possible values are one of the following:
NdisClass802_3Priority
The underlying NIC’s medium requires that drivers specify per-packet priority, while its driver uses Ethernet emulation to communicate with bound protocols.

A bound protocol can determine whether the underlying NIC miniport’s native medium requires prioritized packets with the OID_802_3_MAC_OPTIONS query. If so, the miniport sets the NDIS_802_3_OPTION_PRIORITY flag.

NdisClassWirelessWanMbxMailbox
The underlying NIC driver examines the ULONG-sized record at ClassInformation to determine whether the mailbox flag should be set for the associated packet. (1 = set mailbox flag, 0 = do not set mailbox flag)
Size
Specifies the number of bytes in the ClassInformation array, including any padding necessary to align the NextEntryOffset of the next record on a 4-byte boundary.
ClassInformation
Specifies the out-of-band information for this record.


MMDRV_MESSAGE_PARAMS

This structure is passed to the WAV_IOControl function.

Syntax

typedef struct {
 UINT uDeviceId;
UINT uMsg;
DWORD dwUser;
DWORD dwParam1;
DWORD dwParam2;
} MMDRV_MESSAGE_PARAMS;

Members

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
One of the Wave Input Driver messages (WIDM_*) or Wave Output Driver messages (WODM_*).
dwUser
Specifies a device instance identifier. For the WODM_OPEN and WIDM_OPEN messages, this is an output member. The device creates an instance identifier and returns it in the address specified as the argument. For all other messages, this is an input member. This member is the instance identifier.
dwParam1
Specifies the first message member. Dependent on message type.
dwParam2
Specifies the second message member. Dependent on message type.

Remarks

The MMDRV_MESSAGE_PARAMS structure is declared in the Wavedev.h file.


NDIS_PACKET

This structure defines the packet descriptors with chained buffer descriptors for which pointers are passed to many Ndis XXX, Miniport XXX, and Protocol XXX functions.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

typedef struct _NDIS_PACKET {
 NDIS_PACKET_PRIVATE Private;
union {
struct {
 UCHAR MiniportReserved[8];
UCHAR WrapperReserved[8];
}; struct {
 UCHAR MacReserved[16];
};
};
 UCHAR ProtocolReserved[1];
} NDIS_PACKET, *PNDIS_PACKET, **PPNDIS_PACKET;

Members

Private
Reserved for use exclusively by NDIS. Drivers must call the appropriate Ndis XXX functions or NDIS-supplied macros to affect the contents of this area.
MiniportReserved
NIC miniport drivers and NDIS intermediate drivers can use this 8-byte area for their own purposes, as long as each driver is given a fresh packet descriptor.
WrapperReserved
Reserved for use exclusively by NDIS.
MacReserved
Reserved for use by legacy full-NIC drivers.
ProtocolReserved
Highest-level protocol drivers and NDIS intermediate drivers can use this variable-sized area for their own purposes as long as each such driver is given a fresh packet descriptor.

Remarks

NDIS drivers must call the NdisAllocatePacket function to allocate all packet descriptors that they use to indicate receives to higher-level drivers with the NdisMIndicateReceivePacket function. NDIS drivers must call NdisAllocatePacket to allocate all packet descriptors that they use for sends to underlying drivers with the NdisSend function, as well as packet descriptors that they pass to the NdisTransferData function.

Chained to each packet descriptor are one or more buffer descriptors mapping buffers that contain network packet data, either received or to be transmitted. NIC drivers and intermediate drivers can allocate packet descriptors with, at most, 16 bytes of ProtocolReserved space for receive indications.

Any buffers allocated by lower-level NDIS drivers must be mapped by buffer descriptors that were allocated from a buffer pool with the NdisAllocateBuffer function. Only highest-level Windows NT protocols can use MDLs set up by still higher-level drivers as substitutes for NDIS_BUFFER-type descriptors.

NDIS drivers typically use their respective XXX Reserved areas to maintain per-packet state about outstanding transfers. For example, a protocol might store a pointer to a protocol-allocated buffer containing look-ahead data, which its ProtocolReceive function has already copied, in the ProtocolReserved area of a packet descriptor that the protocol allocates for a call to NdisTransferData.

While a particular packet descriptor is being used in a transfer operation, a single driver can use the MiniportReserved area and a single driver can use the ProtocolReserved. Consequently, NDIS intermediate drivers, which have both Miniport XXX and Protocol XXX functions, cannot use these areas in incoming packet descriptors for their own purposes.

Instead, NDIS intermediate drivers must repackage each incoming packet in a fresh packet descriptor before it passes the transfer request down to an underlying driver or up to a higher-level driver.

This strategy ensures that the NDIS intermediate driver and the underlying driver each have a MiniportReserved area to use, that the intermediate driver and overlying protocol each have a ProtocolReserved area to use, and that the intermediate driver has a convenient and economical way to maintain per-packet state information about all current transfers. This also ensures that NDIS has correct information in the Private portion of each packet descriptor.

Drivers that supply and consume out-of-band data on network transfers and drivers that support multipacket receives and/or sends must use the member-specific NDIS_GET/SET_XXX macros or the NDIS_OOB_DATA_FROM_PACKET macro to access the NDIS_PACKET_OOB_DATA structure associated with each packet descriptor.

When a protocol driver calls the NdisSend function with a packet descriptor, it relinquishes ownership of the following until that packet descriptor is returned to its ProtocolSendComplete function:

  • The protocol-allocated packet descriptor(s)
  • All data buffers mapped by buffer descriptors chained to the packet descriptor(s)
  • All NDIS_PACKET_OOB_DATA structures associated with each protocol-allocated packet descriptor
  • Any out-of-band data buffer specified in an NDIS_PACKET_OOB_DATA structure for an associated buffer descriptor

See Also

NdisAllocateBuffer, NdisAllocatePacket, NdisChainBufferAtBack, NdisChainBufferAtFront, NdisCopyFromPacketToPacket, NdisFreePacket, NdisGetFirstBufferFromPacket, NdisGetPacketFlags, NdisMSendComplete, NdisMTransferDataComplete, NDIS_PACKET_OOB_DATA, NdisQueryPacket, NdisRecalculatePacketCounts, NdisReinitializePacket, NdisReturnPackets, NdisSend, NdisSetPacketFlags, NdisTransferData, NdisUnchainBufferAtBack, NdisUnchainBufferAtFront


NDIS_PACKET_OOB_DATA

This structure specifies out-of-band information associated with a packet descriptor, used by drivers whose media supplies, requires, or accepts out-of-band information, such as packet priorities, and by drivers that support multipacket receives and/or sends.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

typedef struct _NDIS_PACKET_OOB_DATA {
union {
 ULONGLONG TimeToSend;
ULONGLONG TimeSent;
};
 ULONGLONG TimeReceived;
UINT HeaderSize;
UINT SizeMediaSpecificInfo;
PVOID MediaSpecificInformation;
NDIS_STATUS Status;
} NDIS_PACKET_OOB_DATA, *PNDIS_PACKET_OOB_DATA;

Members

TimeToSend
Specifies the time, in system time units, at which a specified packet should be transmitted over the network.

Protocols can set this time stamp before passing an array of packet descriptor pointers to the NdisSendPackets function or a packet descriptor pointer to the NdisSend function.

The MiniportSendPackets or MiniportSend functions of underlying drivers can retrieve the value of this time stamp to determine when the specified packet(s) should be transmitted over the network. Usually, only the lowest-level underlying driver retrieves this time stamp.

TimeSent
Specifies the time, in system time units, at which a received packet was transmitted over the network from a remote node.

NIC drivers and, possibly, intermediate drivers that export only a set of Miniport XXX functions set this time stamp before indicating receive packet(s).

The ProtocolReceivePacket functions of drivers bound above such a miniport can retrieve the value of this time stamp to determine when any particular packet was transmitted from the remote node. If the ProtocolReceive function is given an indication and the underlying driver sets this timestamp, ProtocolReceive can call NdisQueryReceiveInformation to retrieve this time stamp.

TimeReceived
Specifies the time, in system time units, at which a specified packet from a remote node on the network was received on the NIC.

NIC drivers and, possibly, intermediate drivers that export only a set of Miniport XXX functions set this time stamp before calling NdisMIndicateReceivePacket with a packet array, which can have one or more pointers to packet descriptors.

The ProtocolReceivePacket functions of drivers bound above any such miniport can retrieve the value of this time stamp to determine when the specified packet(s) were received. If the ProtocolReceive function is given an indication and the underlying driver sets this time stamp, ProtocolReceive can call NdisQueryReceiveInformation to retrieve this time stamp.

HeaderSize
Specifies the size, in bytes, of the medium-specific header contained in the buffer mapped by the initial buffer descriptor chained to the packet descriptor.

Lower-level drivers set this member for subsequent receive indication(s) according to the medium that each driver’s MiniportInitialize function elected to support.

The ProtocolReceivePacket functions of drivers bound above such a miniport can retrieve the value of this member to determine how to process the medium-specific net packet.

SizeMediaSpecificInfo
Specifies the size, in bytes, of the buffer in the MediaSpecificInformation structure.

A driver must set this member if it supplies out-of-band information with a packet to be sent or indicated.

MediaSpecificInformation
Specifies the address of a driver-allocated buffer. This buffer contains any out-of-band data, such as packet priority, that accompanies the net packet specified with the packet descriptor. The out-of-band data has been set up either by the allocating protocol for a send or by the allocating miniport for a receive indication.

Either type of driver can retrieve the address of the out-of-band data buffer and its size to determine how to process or interpret the send or receive specified with the incoming packet descriptor. If the ProtocolReceive function is given an indication and the underlying driver supplies this information, ProtocolReceive can call NdisQueryReceiveInformation to retrieve the virtual range of this buffer.

Status
Specifies the current status of the packet descriptor and the ownership of all driver-allocated resources specified with the packet descriptor.

Only lower-level drivers and NDIS set this member.

A miniport can set this member before it calls NdisMIndicateReceivePacket to indicate how soon it needs to regain ownership of its allocated resources specified in the associated packet descriptor(s). It can retrieve this value on return from NdisMIndicateReceivePacket to determine whether the resources specified with the packet descriptor for its indication can be prepared for reuse immediately.

A miniport can set this member in its MiniportSendPackets function to complete an incoming send immediately, to notify NDIS that it completes the request asynchronously, or to request that NDIS requeue some or all of the incoming packet array and resubmit those packet descriptor(s) to MiniportSendPackets later.

A protocol cannot retrieve this value to determine the completion status of a send on return from its call to the NdisSendPackets or the NdisSend function.

Remarks

Every packet descriptor allocated with the NdisAllocatePacket function has one of these structures associated with it. Only drivers that support multipacket sends and/or receives and drivers that supply out-of-band information, such as packet priority, with each network packet to be transferred use the OOB block. Nevertheless, every NDIS driver that allocates packet descriptors for transfers between bound drivers must allocate those packet descriptors with NdisAllocatePacket from the packet pool that each such NDIS driver usually allocates when it initializes.

In general, drivers of high-capacity busmaster DMA NICs are most likely to support multipacket receives and sends because such an NIC driver makes the greatest performance gains by supporting multipacket transfers. Any protocol that binds itself to or above such an underlying NIC driver should also support multipacket sends and receives for maximum performance.

If such a protocol also binds itself above another NIC driver without multipacket transfer support, NDIS handles multipacket sends and single-packet receives in a manner transparent to both drivers by always calling the protocol’s ProtocolReceive function and by calling that NIC driver’s MiniportSend function with a single packet per call. Similarly, if a protocol that does not support multipacket transfers binds itself above an NIC driver that does, NDIS handles multipacket receive indications and single packet sends in a manner transparent to both drivers, although the MiniportSendPackets function of the underlying NIC driver is given only a single send request per call to NdisSend from such a protocol.

All time stamps set in these structures associated with packet descriptors are expressed in system time units as the number of 100-nanosecond intervals since 12:00 a.m. January 1, 1601.

NDIS drivers can call the NdisGetCurrentSystemTime function when they set these time stamps with the NDIS_SET_PACKET_TIME_XXX macros. Still higher-level drivers or system components can convert these time stamps into locale-specific values more meaningful to the user.

Any out-of-band information specified in the SizeMediaSpecificInfo and MediaSpecificInformation members is medium-type-specific. For example, some types of media require protocols to specify a packet priority for each packet that they send and require NIC drivers to specify a packet priority with each receive packet that they indicate. Such an NIC driver must call NdisMIndicateReceivePacket to fulfill the requirements of these types of media.

Although NDIS provides support for a range of priority values from 0 through 7, some media support only two levels of priority. For these types of media, NDIS drivers should map values 0 through 3 to the medium-specific normal priority value, usually 0 for such media types, and values 4 through 7 to the medium-specific high priority value, usually one for such media types.


NDIS_PROTOCOL_CHARACTERISTICS

This structure is used to specify the version numbers and various callback functions for a protocol.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

typedef struct _NDIS_PROTOCOL_CHARACTERISTICS {
 UCHAR MajorNdisVersion;
UCHAR MinorNdisVersion;
UINT Reserved;
OPEN_ADAPTER_COMPLETE_HANDLER OpenAdapterCompleteHandler;
CLOSE_ADAPTER_COMPLETE_HANDLER CloseAdapterCompleteHandler;
SEND_COMPLETE_HANDLER SendCompleteHandler;
TRANSFER_DATA_COMPLETE_HANDLER TransferDataCompleteHandler;
RESET_COMPLETE_HANDLER ResetCompleteHandler;
REQUEST_COMPLETE_HANDLER RequestCompleteHandler;
RECEIVE_HANDLER ReceiveHandler;
RECEIVE_COMPLETE_HANDLER ReceiveCompleteHandler;
STATUS_HANDLER StatusHandler;
STATUS_COMPLETE_HANDLER StatusCompleteHandler;
NDIS_STRING Name;
RECEIVE_PACKET_HANDLER ReceivePacketHandler;
BIND_HANDLER BindAdapterHandler;
UNBIND_HANDLER UnbindAdapterHandler;
TRANSLATE_HANDLER TranslateHandler;
UNLOAD_PROTOCOL_HANDLER UnloadHandler;
} NDIS_PROTOCOL_CHARACTERISTICS, *PNDIS_PROTOCOL_CHARACTERISTICS

Members

MajorNdisVersion
Specifies the major version of the NDIS library that the driver is using. The current value is 0x04 although the NDIS library continues to support existing drivers developed for NDIS V3.0.

This member must be set to 0x04 if the caller if the caller is an NDIS intermediate driver or if the caller sets entry points in any members following Name.

MinorNdisVersion
Specifies the minor NDIS version. The current value is 0x00 although NDIS continues to support existing drivers.
Reserved
This member is reserved for system use.
OpenAdapterCompleteHandler
Specifies the entry point of the caller’s ProtocolOpenAdapterComplete function.
CloseAdapterCompleteHandler
Specifies the entry point of the caller’s ProtocolCloseAdapterComplete function.
SendCompleteHandler
Specifies the entry point of the caller’s ProtocolSendComplete function.
TransferDataCompleteHandler
Specifies the entry point of the caller’s ProtocolTransferDataComplete function.
ResetCompleteHandler
Specifies the entry point of the caller’s ProtocolResetComplete function.
RequestCompleteHandler
Specifies the entry point of the caller’s ProtocolRequestComplete function.
ReceiveHandler
Specifies the entry point of the caller’s ProtocolReceive function.
ReceiveCompleteHandler
Specifies the entry point of the caller’s ProtocolReceiveComplete function.
StatusHandler
Specifies the entry point of the caller’s ProtocolStatus function.
StatusCompleteHandler
Specifies the entry point of the caller’s ProtocolStatusComplete function.
Name
Specifies a pointer to a buffered, caller-initialized counted string, in the system-default character set, naming the driver.

NdisRegisterProtocol converts the supplied string to upper case, so a protocol driver writer cannot assume that changing the case of an already registered protocol name creates a unique name for the driver.

ReceivePacketHandler
Specifies the entry point of the caller’s ProtocolReceivePacket function, if any, or NULL. Protocols that bind to any driver that supports multipacket receive indications should supply a ProtocolReceivePacket function to enhance their performance. MajorNdisVersion must be set to 0x04.
BindAdapterHandler
Specifies the entry point of the caller’s ProtocolBindAdapter function, if any, or NULL. NDIS intermediate drivers usually supply a ProtocolBindAdapter function, which both makes them Plug and Play–ready and allows the intermediate driver to call NdisIMRegisterLayeredMiniport and to defer full driver initialization until underlying NIC drivers have initialized. MajorNdisVersion must be set to 0x04.
UnbindAdapterHandler
Specifies the entry point of the caller’s ProtocolUnbindAdapter function, if any, or NULL. NDIS drivers that supply a ProtocolBindAdapter function also must supply a ProtocolUnbindAdapter function. MajorNdisVersion must be set to 0x04.
TranslateHandler
Specifies the entry point of the caller’s ProtocolTranslate function, if any, or NULL. Such a function currently is not called, and this member is reserved for future use by Plug and Play–aware protocols. MajorNdisVersion must be set to 0x04.
UnloadHandler
Set to NULL by Windows CE protocol drivers. MajorNdisVersion must be set to 0x04.


NDIS_REQUEST

This structure specifies a packet set up by NDIS or by a protocol for a call to the NdisRequest function. NDIS submits these requests to the underlying driver’s MiniportQueryInformation or MiniportSetInformation functions.

At a Glance

Header file: | Ndis.h
Windows CE versions: | 2.0 and later

Syntax

typedef struct _ NDIS_REQUEST {
 UCHAR MacReserved[16];
NDIS_REQUEST _TYPE RequestType;
union _DATA {
struct QUERY_INFORMATION {
 NDIS_OID Oid;
PVOID InformationBuffer;
UINT InformationBufferLength;
UINT BytesWritten;
UINT BytesNeeded;
} QUERY_INFORMATION;
struct SET_INFORMATION {
 NDIS_OID Oid;
PVOID InformationBuffer;
UINT InformationBufferLength;
UINT BytesRead;
UINT BytesNeeded;
} SET_INFORMATION;
} DATA;
} NDIS_REQUEST, *PNDIS_REQUEST;

Members

MacReserved[16]
Specifies a 16-byte area reserved for use by the underlying driver.
RequestType
Specifies the request type as one of the following:
NdisRequestQueryInformation
Specifies a query-information request. NDIS forwards such a request to the underlying driver’s MiniportQueryInformation function.
NdisRequestSetInformation
Specifies a set-information request. NDIS forwards such a request to the underlying driver’s MiniportSetInformation function.
NdisRequestQueryStatistics
Specifies a query-statistics request. For most statistics queries, NDIS satisfies the request itself. Otherwise, NDIS forwards such request to the underlying driver’s MiniportQueryInformation function. This type of request originates in a user-mode application, never in a protocol driver.

For any of the preceding values, the OID_XXX specified in the Oid member must be compatible with the type of operation requested.

NdisRequestOpen
This type is obsolete. A protocol driver calls NdisOpenAdapter instead.
NdisRequestClose
This type is obsolete. A protocol driver calls NdisCloseAdapter instead.
NdisRequestSend
This type is obsolete. A protocol driver calls NdisSend or NdisSendPackets instead.
NdisRequestTransferData
This type is obsolete. A protocol driver calls NdisTransferData instead.
NdisRequestReset
This type is obsolete. A protocol driver calls NdisReset instead.
NdisRequestGeneric1
Specifies an NIC-driver-specific request.
NdisRequestGeneric2
Specifies an NIC-driver-specific request.
NdisRequestGeneric3
Specifies an NIC-driver-specific request.
NdisRequestGeneric4
Specifies an NIC-driver-specific request.
Oid
Specifies the object identifier of the requested operation. The value is an OID_XXX code.
InformationBuffer
Pointer to a buffer into which the underlying driver or NDIS returns the requested information for queries or from which the underlying driver reads caller-supplied information for sets.
InformationBufferLength
Specifies the size, in bytes, of the buffer at InformationBuffer. The value at Oid determines the value appropriate to this member.
BytesWritten
Specifies the number of bytes that the underlying driver or NDIS transfers into the buffer at InformationBuffer for query-information requests. If NdisRequest returns NDIS_STATUS_INVALID_LENGTH, the value of this member is meaningless.
BytesRead
Specifies the number of bytes that the underlying driver read from the buffer at InformationBuffer for set-information requests.
BytesNeeded
Specifies the number of bytes needed to return query information or to carry out the set operation requested by the given OID_XXX code.

If NdisRequest returns NDIS_STATUS_SUCCESS, the value of this member is meaningless. If the InformationBufferLength is too small for the given OID_XXX on a query, this member indicates how large a buffer is required to satisfy the request. If the buffer at InformationBuffer does not contain sufficient data for the given OID_XXX on a set, this member indicates how much data is required.

Remarks

A protocol should allocate nonpaged memory for the buffer at InformationBuffer and for this structure itself. Passing in a packet or buffer allocated from paged memory can cause fatal page faults because the underlying driver(s) run at IRQL DISPATCH_LEVEL to carry out the requested operation.

This structure contains a DATA substructure for each type of operation that a protocol driver can request of an underlying driver. Before calling NdisRequest, the protocol fills in the relevant members of the substructure that represents the query or set operation that it specified in the Oid member. NDIS or the underlying driver fills in the remaining members before it returns control to the caller.

The NdisRequestGeneric types are available for NIC drivers that create their own internal requests. To indicate a requested operation, an NIC driver sets an internal variable to one of these types.

See Also

NdisCloseAdapter, NdisMQueryInformationComplete, NdisMSetInformationComplete, NdisOpenAdapter, NdisRequest, NdisReset, NdisSend, NdisTransferData


NLED_COUNT_INFO

This structure contains information about the number of notification LEDs for the system.

Syntax

struct NLED_COUNT_INFO {
UINT cLeds;
};

Members

cLeds
Specifies the count of LEDs for the system.

Remarks

A device usually has one notification LED, although multiple notification devices-LEDs or otherwise-are allowed. For example, multiple notification devices would be appropriate if you want users to be able to select between notification by a blinking LED or by a vibrating buzzer, as is typical with pagers.

Implement this GWES data structure as part of porting native device drivers. This structure is declared in the Nled.h header file.


NLED_SETTINGS_INFO

This structure contains information about the capabilities of the specified LED.

Syntax

struct NLED_SETTINGS_INFO {
UINT Lednum;
INT OffOnBlink;
LONG TotalCycleTime;
LONG OnTime;
LONG OffTime;
INT MetaCycleOn;
INT MetaCycleOff;
};

Members

Lednum
LED number. The first LED is 0.
OffOnBlink
Current setting. The following values are defined:
0
Off.
1
On.
2
Blink.
TotalCycleTime
Total cycle time of a blink, in microseconds.
OnTime
On time of the cycle, in microseconds.
MetaCycleOn
Number of on blink cycles.
MetaCycleOff
Number of off blink cycles.

Remarks

This structure is used with the NLedGetDeviceInfo and NLEDSetDevice functions.

This GWES data structure is implemented as part of porting native device drivers. It is declared in the Nled.h header file.


NLED_SUPPORTS_INFO

This structure contains information about the capabilities of the specified LED.

Syntax

struct NLED_SUPPORTS_INFO {
UINT Lednum;
LONG lCycleAdjust;
BOOL fAdjustTotalCycleTime;
BOOL fAdjustOnTime;
BOOL fAdjustOffTime;
BOOL fMetaCycleOn;
BOOL fMetaCycleOff;
};

Members

Lednum
Number of the LED. The first LED is 0.
lCycleAdjust
Granularity of the cycle-time adjustments, in microseconds.
fAdjustTotalCycleTime
TRUE, if the LED has an adjustable total cycle time; otherwise, it is FALSE.
fAdjustOnTime
TRUE, if the LED has a separate on time; otherwise, it is FALSE.
fMetaCycleOn
TRUE, if the LED can blink n cycles, pause, and blink n cycles; otherwise, it is FALSE.
fMetaCycleOff
TRUE, if the LED can blink n cycles, pause n cycles, and blink n cycles; otherwise, it is FALSE.

Remarks

This structure is used with the NLedGetDeviceInfo and NLEDSetDevice functions.

Implement this GWES data structure as part of porting built-in device drivers. It is declared in the Nled.h header file.


PARSED_CFTABLE

This structure is used by the CardGetParsedTuple function to return data for the CISTPL_CFTABLE_ENTRY tuple code. The PARSED_CFTABLE structure represents, in a fixed form, the information contained in a variable-length CISTPL_CFTABLE_ENTRY tuple code as parsed by CardGetParsedTuple.

Syntax

typedef struct {
POWER_DESCR VccDescr;
POWER_DESCR Vpp1Descr;
POWER_DESCR Vpp2Descr;
UINT32 IOLength[MAX_IO_RANGES];
UINT32 IOBase[MAX_IO_RANGES];
UINT8 NumIOEntries;
UINT8 ConfigIndex;
UINT8 ContainsDefaults;
UINT8 IFacePresent;
UINT8 IFaceType;
UINT8 BVDActive;
UINT8 WPActive;
UINT8 ReadyActive;
UINT8 WaitRequired;
UINT8 IOAccess;
UINT8 NumIOAddrLines;
} PARSED_CFTABLE;

Members

VccDescr
[OUT] Specifies the power description for the Vcc voltage supply.
Vpp1Descr
[OUT] Specifies the power description for the Vpp1 voltage supply.
Vpp2Descr
[OUT] Specifies the power description for the Vpp2 voltage supply. If the ValidMask member of the POWER_DESC structure indicates no valid voltage values for Vpp2, the values in Vpp1Descr describe both Vpp1 and Vpp2.
IOLength[MAX_IO_RANGES]
Specifies an array of the lengths of the I/O address ranges described by this CISTPL_CFTABLE_ENTRY. IOLength[0] is the length of the I/O address range starting at address IOBase[0].
IOBase[MAX_IO_RANGES]
[OUT] Specifies an array of the base addresses of the I/O address ranges described by this CISTPL_CFTABLE_ENTRY.
NumIOEntries
[OUT] Specifies the number of I/O addresses in the arrays IOLength and IOBase.
ConfigIndex
[OUT] Specifies a configuration index value. The PC Card will conform to the behavior described by this CISTPL_CFTABLE_ENTRY if this value is written to the configuration option register. See CardRequestConfiguration.
ContainsDefaults
[OUT] The values described by this CISTPL_CFTABLE_ENTRY can be used as defaults for subsequent CISTPL_CFTABLE_ENTRY parsing.
IFacePresent
[OUT] If this member is not 0, the IFaceType, BVDActive, WPActive, ReadyActive, and WaitRequired members contain valid values.
IFaceType
[OUT] Specifies one of the following interface types:
0 (0)
Indicates a memory-only interface.
1
Indicates an I/O interface.
2, 3
Reserved.
4–7
Indicates a custom interface.
8–15
Reserved.
BVDActive
[OUT] Specifies TRUE if BVD1 and BVD2 are active in the pin replacement register (PRR).
WPActive
[OUT] Specifies TRUE if the card write protect is active in the PRR.
ReadyActive
[OUT] Specifies TRUE if the READY signal is active in the PRR.
WaitRequired
[OUT] Specifies TRUE if the WAIT signal is required for memory cycles.
IOAccess
[OUT] Specifies one of the following I/O access options:
1
Indicates 8-bit only.
2
Indicates 8-bit access to 16-bit is unsupported.
3
Indicates 8-bit access to 16-bit is supported.
NumIOAddrLines
[OUT] Specifies the number of I/O address lines. If 0, the socket controller provides address decode. If the number is from 1 through 26, the value is the number of address lines decoded.

See Also

CardGetParsedTuple, PARSED_CONFIG, POWER_DESCR


PARSED_CONFIG

This structure is used by the CardGetParsedTuple function to return data for the CISTPL_CONFIG tuple code.

Syntax

typedef struct {
UINT32 ConfigBase;
UINT8 RegMask;
UINT8 LastConfigIndex;
} PARSED_CONFIG;

Members

ConfigBase
[OUT] Specifies the base address in attribute memory of the function and configuration registers. The value is in virtual attribute space units, so a value of 80 indicates that the registers start at the real address 160 in attribute space.
RegMask
[OUT] Specifies a bitmask indicating which registers are supported.
LastConfigIndex
[OUT] Specifies the index of the last configuration entry supported.

Remarks

The CardGetParsedTuple function only uses 1 byte of the register presence mask. It does not parse custom interface subtuples.

See Also

CardGetParsedTuple, PARSED_CFTABLE, POWER_DESCR


PDCARD_ADAPTER_INFO

This structure is used by the PDCardInquireAdapter function to report the characteristics and capabilities of the socket controller.

Syntax

typedef struct {
 UINT32 uMemGranularity;
UINT8 fAdapterCaps;
UINT8 uCacheLine;
UINT16 uPowerEntries;
} PDCARD_ADAPTER_INFO;

Members

uMemGranularity
For Windows CE 2.0 and later, this value must be 1. For versions of Windows Ce prior to 2.0, this value should be 1 for most hardware platforms, although other values can be used if needed to overcome hardware limitations.
fAdapterCaps
Bit-encoded capabilities.
uCacheLine
Number of 32-bit WORDs in a cache line.
uPowerEntries
Number of PDCARD_POWER_ENTRY structures immediately following this structure in RAM.

Remarks

This structure is declared in the Sockserv.h header file. It supports the implementation of the driver described in sample PC Card socket driver.


PDCARD_POWER_ENTRY

This structure indicates the voltage levels that a socket controller can produce.

Syntax

typedef struct {
UINT8 uPowerLevel;
UINT8 fSupply;
} PDCARD_POWER_ENTRY;

Members

uPowerLevel
Specifies the voltage in 0.1 volt increments.
fSupply
Specifies the voltage source (Vcc, Vpp1 or Vpp2).

Remarks

This structure is declared in the Sockserv.h header file. It supports the implementation of the driver described in sample PC Card socket driver.


PDCARD_SOCKET_STATE

This structure is used by the PDCardGetSocket and PDCardSetSocket functions to retrieve or change the specified socket’s characteristics.

Syntax

typedef struct {
 UINT8 fSocketCaps;
UINT8 fInterruptEvents;
UINT8 fNotifyEvents;
UINT8 fControlCaps;
UINT8 fInterfaceType;
UINT8 fIREQRouting;
UINT8 fVcc;
UINT8 uVpp1;
UINT8 uVpp2;
} PDCARD_SOCKET_STATE;

Members

fSocketCaps
Specifies socket capabilities.
fInterruptEvents
Specifies status change interrupt mask. The initial state of this member indicates which events can cause a status change interrupt.
fNotifyEvents
Specifies latched socket state.
fControlCaps
Control capabilities.
fInterfaceType
Specifies memory-only or memory and I/O.
fIREQRouting
Enable or disable IREQ.
fVcc
Vcc power entry index and status.
uVpp1
Vpp1 power entry index.
uVpp2
Vpp2 power entry index.

Remarks

This structure PDCARD_SOCKET_STATE is declared in the Sockserv.h header file. It supports the implementation of the driver described in sample PC Card socket driver.


PDCARD_WINDOW_INFO

This structure is used by the PDCardInquireWindow function to report a memory or I/O window’s characteristics and capabilities.

Syntax

typedef struct {
 UINT16 fSockets;
UINT16 fWindowCaps;
UINT16 fMemoryCaps;
UINT16 fIOCaps;
UINT32 uMemFirstByte;
UINT32 uMemLastByte;
UINT32 uMemMinSize;
UINT32 uMemMaxSize;
UINT32 uMemGranularity;
UINT32 uMemBase;
UINT32 uMemOffset;
UINT32 uIOFirstByte;
UINT32 uIOLastByte;
UINT32 uIOMinSize;
UINT32 uIOMaxSize;
UINT32 uIOGranularity;
UINT8 uAddressLines;
UINT8 fSlowest;
UINT8 fFastest;
} PDCARD_WINDOW_INFO;

Members

fSockets
A flag indicating the socket number. Bit 0 corresponds to socket 0, and bit 1 corresponds to socket 1.
fWindowCaps
Specifies bit-encoded window capabilities.
fMemoryCaps
Specifies bit-encoded memory window capabilities.
fIOCaps
Specifies bit-encoded I/O window capabilities.
uMemFirstByte
Specifies the physical address of the first addressable byte.
uMemLastByte
Specifies the physical address of the last addressable byte.
uMemMinSize
Specifies the minimum memory window size, in bytes.
uMemMaxSize
Specifies the maximum memory window size.
uMemGranularity
Specifies the required window granularity.
uMemBase
Specifies the required window base address alignment.
uMemOffset
Specifies the required card offset alignment.
uIOFirstByte
Specifies the physical address of the first addressable byte.
uIOLastByte
Specifies the physical address of the last addressable byte.
uIOMinSize
Specifies the minimum memory window size, in bytes.
uIOMaxSize
Specifies the maximum memory window size, in bytes.
uIOGranularity
Specifies the required memory window granularity.
uAddressLines
Specifies the number of I/O lines decoded.
fSlowest
Specifies the bit-encoded slowest access speed.
fFastest
Specifies the bit-encoded fastest access speed.

Remarks

This structure is declared in the Sockserv.h header file. It supports the implementation of the driver described in sample PC Card socket driver.


PDCARD_WINDOW_STATE

This structure is used by the PDCardGetWindow and PDCardSetWindow functions to report or change a memory or I/O window’s state.

Syntax

typedef struct {
 UINT16 uSocket;
UINT8 fState;
UINT8 fSpeed;
UINT32 uSize;
UINT32 uBase;
UINT32 uOffset;
} PDCARD_WINDOW_STATE;

Members

uSocket
Specifies the socket number to which this window is mapped.
fState
Specifies a bit-encoded window state.
fSpeed
Specifies the bit-encoded access speed.
uSize
Specifies the memory window size, in bytes.
uBase
Specifies the physical address of beginning of window.
uOffset
Specifies the offset in PC card memory.

Remarks

This structure is declared in the Sockserv.h header file. It supports the implementation of the driver described in sample PC Card socket driver.


POWER_DESCR

This structure contains the characteristics of one of the PC Card voltage sources: Vcc, Vpp1, or Vpp2. The PARSED_CFTABLE structure uses the POWER_DESCR structure to define its VccDescr, Vpp1Descr and Vpp2Descr members.

Syntax

typedef struct {
UINT8 ValidMask;
UINT8 NominalV;
UINT8 MinV;
UINT8 MaxV;
UINT8 StaticI;
UINT8 AvgI;
UINT8 PeakI;
UINT8 PowerDownI;
} POWER_DESCR;

Members

ValidMask
[OUT] Specifies a bitmask identifying the members in the POWER_DESCR structure containing valid values. A CISTPL_CFTABLE_ENTRY tuple might not include all seven power characteristics. If the first bit of ValidMask is 1, the NominalV member contains a valid voltage. If the following bit is 1, the MinV member is valid, and so on.
NominalV
[OUT] Specifies the nominal operating supply voltage.
MinV
[OUT] Specifies the minimum operating supply voltage.
MaxV
[OUT] Specifies the maximum operating supply voltage.
StaticI
[OUT] Specifies that continuous supply current is required
AvgI
[OUT] Specifies that maximum current is required averaged over 1 second.
PeakI
[OUT] Specifies that maximum current is required averaged over 10 milliseconds.
PowerDownI
[OUT] Specifies that power-down supply current is required.

Remarks

Voltages are expressed in one-tenth volt increments, so a value of 50 represents 5 volts. The currents are expressed in milliamps.

See Also

CardGetParsedTuple, PARSED_CFTABLE, PARSED_CONFIG, POWER_DESCR


TOUCHPANEL_POINT_SAMPLE

This structure defines the values available for each sample from the analog-to-digital converter (ADC).

Syntax

typedef struct {
 USHORT XSample;
USHORT XzaSample;
USHORT XzbSample;
USHORT YSample;
USHORT YzaSample;
USHORT YzbSample;
} TOUCHPANEL_POINT_SAMPLE;

Members

XSample
Specifies the x-coordinate in pixels. The top left corner is (0,0).
XzaSample
Not used.
XzbSample
Not used.
YSample
Specifies the y-coordinate in pixels.
YzaSample
Not used.
YzbSample
Not used.

Remarks

This structure supports the implementation of the touch screen PDD. It is declared in the Tchaud.h header file.


USB_DRIVER_SETTINGS

This structure contains the members for USB drivers.

Syntax

typedef struct {
 DWORD dwCount;
DWORD dwVendorId;
DWORD dwProductId;
DWORD dwReleaseNumber;
DWORD dwDeviceClass;
DWORD dwDeviceSubClass;
DWORD dwDeviceProtocol;
DWORD dwInterfaceClass;
DWORD dwInterfaceSubClass;
DWORD dwInterfaceProtocol;
} USB_DRIVER_SETTINGS;

Members

dwCount
Specifies the size, in bytes, of the structure.
dwVendorId
Specifies the vendor identifier in the device descriptor.
dwProductId
Specifies the product identifier in the device descriptor.
dwReleaseNumber
Specifies the release number in the device descriptor.
dwDeviceClass
Specifies the device class in the device descriptor.
dwDeviceSubClass
Specifies the device subclass in the device descriptor.
dwDeviceProtocol
Specifies the protocol in the device descriptor.
dwInterfaceClass
Specifies the class in the interface descriptor.
dwInterfaceSubClass
Specifies the subclass in the interface descriptor.
dwInterfaceProtocol
Specifies the protocol in the interface descriptor.

Remarks

This structure is passed to the RegisterClientSettings function to enable the USBD module to recognize a USB driver. The contents of this structure control how the USBD module matches this driver against the members of actual USB devices at the time when a device is connected to a Windows CE–based platform. Any of the members may be set to USB_NO_INFO, which indicates that the driver is loaded by default if all other members match and no other driver is a better match. This structure is declared in the Usbdi.h header file.


WAVEOPENDESC

This structure contains information needed by waveform input and output drivers.

Syntax

typedef struct {
 HWAVE hWave;
LPWAVEFORMATEX lpFormat;
DWORD dwCallback;
DWORD dwInstance;
UINT uMappedDeviceID;
} WAVEOPENDESC;

Members

hWave
Handle to the device, as assigned by Waveapi.dll.
lpFormat
Pointer to a WAVEFORMATEX structure, indicating the waveform data format requested by the client.
dwCallback
Handle to the callback thread inside Waveapi.dll.
dwInstance
Specifies the dwCallbackInstance member that the client specified when calling the waveInOpen or the waveOutOpen function.
uMappedDeviceID
Specifies the device identifier of a mapped device.

Remarks

This structure is created by the Waveapi.dll file and passed to the driver with a WODM_OPEN or WIDM_OPEN message.

This structure is declared in the Mmddk.h header file.


Messages

This section documents the messages that ACM drivers and audio stream interface drivers must respond to.


ACMDM_DRIVER_ABOUT

This message requests an ACM driver to display its About dialog box.

Parameters

dwDriverID
Specifies a driver instance identifier. The driver returns this value in response to the ACM_Open function.
hDriver
Handle to a driver.
uMsg
Specifies this message.
lParam1
Contains a validated window handle, which the driver should use to specify the parent window for the About dialog box. The value also can be -1L.
lParam2
Not used.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR error values declared in the Mmsystem.h header file or one of the ACMERR error values declared in the Msacm.h header file. If the driver does not provide an About dialog box, it returns MMSYSERR_NOTSUPPORTED.

Remarks

The ACM (Waveapi.dll) sends this message by calling the ACM driver’s ACM_IOControl function entry point through the DeviceIoControl function.

If an ACM driver provides an About dialog box, it displays the box in response to this message. If an ACM driver does not provide an About dialog box, it returns MMSYSERR_NOTSUPPORTED. In the latter case, the ACM displays a default About dialog box.

However, if lParam1 is –1L, the driver does not display its About dialog box. Instead, it returns MMSYSERR_NOERROR if it provides an About dialog box and MMSYSERR_NOTSUPPORTED if it does not provide an About dialog box.

For more information, see the Microsoft Windows NT DDK.


ACMDM_DRIVER_DETAILS

This message requests an ACM driver to return detailed information about itself.

Parameters

dwDriverID
Specifies a driver instance identifier. The driver returns this value in response to the ACM_Open function.
hDriver
Handle to a driver.
uMsg
Specifies this message.
lParam1
Pointer to an ACMDRIVERDETAILS structure. This structure is declared in the Msacm.h header file.
lParam2
Not used.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR error values declared in the Mmsystem.h header file or one of the ACMERR error values declared in the Msacm.h header file.

Remarks

The ACM (Waveapi.dll) sends this message by calling the ACM driver’s ACM_IOControl entry point through the DeviceIoControl function. The ACM sends this message when an application calls the acmDriverDetails function, which is described in the Windows CE Platform SDK.

Before calling the driver’s ACM_IOControl function, the ACM verifies that lParam1 contains a valid pointer and that the cbStruct member of ACMDRIVERDETAILS contains a size value of at least 4.

The driver fills in the members of ACMDRIVERDETAILS, up to the number of bytes specified by the cbStruct member.

ACM drivers must support this message.


ACMDM_DRIVER_NOTIFY

This message notifies an ACM driver of changes to other ACM drivers.

Parameters

dwDriverID
Specifies a driver instance identifier. The driver returns this value in response to the ACM_Open function.
hDriver
Handle to a driver.
uMsg
Specifies this message.
lParam1
Not used.
lParam2
Not used.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR error values declared in the Mmsystem.h header file or one of the ACMERR error values declared in the Msacm.h header file.

Remarks

Each time a client calls the acmDriverAdd, acmDriverRemove, or acmDriverPriority functions, the ACM (Waveapi.dll) sends this message by calling the ACM driver’s ACM_IOControl entry point through the DeviceIoControl function. For more information about these functions, see the Windows CE Platform SDK.

ACM driver support for this message is optional. If the driver supports this message, it can call ACM functions, such as acmEnumDrivers and acmMetrics, to determine which drivers have been added, removed, enabled, disabled, or changed in priority. Note, however, that Windows CE versions 2.12 and earlier do not issue this message, because ACM drivers cannot be dynamically added or removed, and their priorities are fixed.


ACMDM_FILTER_DETAILS

This message requests an ACM driver to return information about a filter associated with a specified filter tag.

Parameters

dwDriverID
Specifies a driver instance identifier. The driver returns this value in response to the ACM_Open function.
hDriver
Handle to a driver.
uMsg
Specifies this message.
lParam1
Pointer to an ACMFILTERDETAILS structure. The structure is declared in the Msacm.h header file.
lParam2
Contains one of the following flags specified by the fdwDetails parameter of the acmFilterDetails function:
ACM_FILTERDETAILSF_INDEX
Indicates that the dwFilterIndex member of ACMFILTERDETAILS contains a filter index. The valid index range is from 0 to 1 less than the cStandardFilters member returned in the ACMFILTERTAGDETAILS structure for the filter tag.
ACM_FILTERDETAILSF_FILTER
Indicates that the client has filled in the WAVEFILTER structure associated with ACMFILTERDETAILS.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR error values declared in the Mmsystem.h header file or one of the ACMERR error values declared in the Msacm.h header file. The following are possible error values.

MMSYSERR_NOTSUPPORTED
The driver does not support filter operations or the specified query operation.
ACMERR_NOTPOSSIBLE
The input parameter values do not represent valid filters or filter tags.

Remarks

The ACM (Waveapi.dll) sends the ACMDM_FILTER_DETAILS message by calling the ACM driver’s ACM_IOControl entry point through the DeviceIoControl function. The ACM sends this message when an application calls the acmFilterDetails function.

An ACM driver that provides filters must support this message.

The client can do either of the following:

  • Specify a filter index to obtain a description of the filter associated with the index.
  • Specify a filter description to validate the filter and obtain the filter’s string description.

The client specifies the filter tag in the dwFilterTag member of ACMFILTERDETAILS. The driver returns the following information for a particular filter belonging to the filter tag:

  • If the ACM_FILTERDETAILSF_INDEX flag is set, the client has specified an index value in the dwFilterIndex member of ACMFILTERDETAILS. The driver fills in WAVEFILTER for the filter associated with the specified index value. It also fills in the szFilter, fdwSupport, and cbStruct members of ACMFILTERDETAILS.
  • If the ACM_FILTERDETAILSF_FILTER flag is set, the client has filled in WAVEFILTER. The driver validates the contents of the structure and fills in the szFilter, fdwSupport, and cbStruct members of ACMFILTERDETAILS.

Before calling the driver’s ACM_IOControl function, the ACM should verify the following conditions:

  • ACMFILTERDETAILS and the associated WAVEFILTER structure are readable and writeable.
  • The size of ACMFILTERDETAILS, contained in its cbStruct member, is at least as large as its defined size. The structure size can be larger than its defined size to allow for a longer szFilter member or to enable newer, larger structure definitions to be used within drivers under development.
  • The size of WAVEFILTER, pointed to by the pwfltr member of ACMFILTERDETAILS, is at least as large as the generic WAVEFILTER structure’s defined size.
  • The fdwSupport member of ACMFILTERDETAILS contains 0.
  • The lParam2 parameter contains a valid flag value.

WAVEFILTER is a generic structure for describing a filter. Generally, extend this structure for your specific filter type. For examples, see VOLUMEWAVEFILTER and ECHOWAVEFILTER in the Mmreg.h header file. When a client sends an ACMDM_FILTER_DETAILS message, it specifies a pointer to a structure that you have defined for the specified filter type. This structure typically is larger than the generic WAVEFILTER.

Before returning, the driver must set the cbStruct member of ACMFILTERDETAILS to the actual number of bytes returned. The value returned in cbStruct must not be greater than the value received from the client.

For more information about format tags and filters, see the Windows NT DDK.

See Also

ACMDM_FILTERTAG_DETAILS


ACMDM_FILTERTAG_DETAILS

This message requests an ACM driver to return information about a filter tag, in the form of an ACMFILTERTAGDETAILS structure.

Parameters

dwDriverID
Specifies a driver instance identifier. The driver returns this value in response to the ACM_Open function.
hDriver
Handle to a driver.
uMsg
Specifies this message.
lParam1
Pointer to an ACMFILTERTAGDETAILS structure. ACMFILTERTAGDETAILS is declared in the Msacm.h header file.
lParam2
Contains one of the following flags specified by the fdwDetails parameter of the acmFilterTagDetails:
ACM_FILTERTAGDETAILSF_INDEX
Indicates that the dwFilterTagIndex member of ACMFILTERTAGDETAILS contains a filter tag index. The valid index range is from 0 to 1 less than the cFilterTags member returned in the driver’s ACMDRIVERDETAILS structure.

The driver should return details for the filter tag associated with the index.

ACM_FILTERTAGDETAILSF_FILTERTAG
Indicates that the dwFilterTag member of ACMFILTERTAGDETAILS contains a filter tag.

The driver returns details for the specified filter tag.

ACM_FILTERTAGDETAILSF_LARGESTSIZE
Indicates that the driver returns details for the filter tag with the largest filter. The dwFilterTag member of ACMFILTERTAGDETAILS can contain a filter tag or WAVE_FILTER_UNKNOWN.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR error values declared in the Mmsystem.h header file or one of the ACMERR error values declared in the Msacm.h header file. The following are possible error values.

MMSYSERR_NOTSUPPORTED
The driver does not support filter operations or the specified query operation.
ACMERR_NOTPOSSIBLE
The input parameter values do not represent valid filters or filter tags.

Remarks

The ACM (Waveapi.dll) sends the ACMDM_FILTERTAG_DETAILS message by calling the ACM driver’s ACM_IOControl entry point through the DeviceIoControl function. The ACM sends this message when an application calls the acmFilterTagDetails function.

An ACM driver that provides filters must support this message.

The client specifies the filter tag in the dwFilterTag member of ACMFILTERTAGDETAILS. The driver returns the following information for a particular tag:

  • If the ACM_FILTERDETAILSF_INDEX flag is set, the client has specified an index value in the dwFilterTagIndex member of ACMFILTERTAGDETAILS. The driver fills in ACMFILTERTAGDETAILS for the filter tag associated with the specified index value.
  • If the ACM_FILTERTAGDETAILSF_FILTERTAG flag is set, the client has specified a filter tag in the dwFilterTag member of ACMFILTERTAGDETAILS. The driver fills in ACMFILTERTAGDETAILS for the specified filter tag.
  • If the ACM_FILTERTAGDETAILSF_LARGESTSIZE flag is set, the driver performs one of two actions:
    • If dwFilterTag contains WAVE_FILTER_UNKNOWN, the driver fills in ACMFILTERTAGDETAILS for the filter tag that has a filter with the largest filter structure size.
    • If dwFilterTag contains a filter tag, the driver fills in ACMFILTERTAGDETAILS for that filter tag, describing the filter with the largest structure size belonging to the specified tag.

Before calling the driver’s ACM_IOControl function, the ACM verifies the following conditions:

  • ACMFILTERTAGDETAILS is readable and writeable.
  • The size of ACMFILTERTAGDETAILS, contained in its cbStruct member, is at least as large as the structure’s defined size. The structure’s size can be larger than its defined size to allow for a longer szFilterTag member or to enable newer, larger structure definitions to be used within drivers under development.
  • The fdwSupport member of ACMFILTERTAGDETAILS contains 0.
  • The lParam2 parameter contains a valid flag value.

Before returning, the driver must set the cbStruct member of ACMFILTERTAGDETAILS to the actual number of bytes returned. The value returned in cbStruct must not be greater than the value received.

For more information about format tags and filter tags, see the Windows NT DDK.

See Also

ACMDM_DRIVER_DETAILS


ACMDM_FORMAT_DETAILS

This message requests an ACM driver to return information about a format associated with a specified format tag.

Parameters

dwDriverID
Specifies a driver instance identifier. The driver returns this value in response to the ACM_Open function.
hDriver
Handle to a driver.
uMsg
Specifies this message.
lParam1
Pointer to an ACMFORMATDETAILS structure. ACMFORMATDETAILS is declared in the Msacm.h header file.
lParam2
Contains one of the following flags specified by the fdwDetails parameter of the acmFormatDetails function:
ACM_FORMATDETAILSF_INDEX
Indicates that the dwFormatIndex member of ACMFORMATDETAILS contains a format index. The valid index range is from 0 to 1 less than the cStandardFormats member returned in ACMFORMATTAGDETAILS for the format tag.
ACM_FORMATDETAILSF_FORMAT
Indicates that the client has filled in the WAVEFORMATEX structure associated with ACMFORMATDETAILS.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR error values declared in the Mmsystem.h header file or one of the ACMERR error values declared in the Msacm.h header file. The following are possible error values.

MMSYSERR_NOTSUPPORTED
The driver does not support the specified query operation.
ACMERR_NOTPOSSIBLE
The input parameter values do not represent valid formats or format tags.

Remarks

The ACM sends this message by calling the ACM driver’s ACM_IOControl entry point through the DeviceIoControl function. The ACM sends this message when an application calls the acmFormatDetails function.

All ACM drivers must support this message.

The client can perform either of the following actions:

  • Specify a format index to obtain a description of the format associated with the index.
  • Specify a format description to validate the format and obtain the format’s string description.

The client specifies the format tag in the dwFormatTag member of ACMFORMATDETAILS. The driver returns the following information for a particular format belonging to the format tag:

  • If the ACM_FORMATDETAILSF_INDEX flag is set, the client has specified an index value in the dwFormatIndex member of ACMFORMATDETAILS. The driver fills in WAVEFORMATEX for the format associated with the specified index value. It also fills in the szFormat, fdwSupport, and cbStruct members of ACMFORMATDETAILS.
  • If the ACM_FORMATDETAILSF_FORMAT flag is set, the client has filled in WAVEFORMATEX. The driver validates the structure contents and, if the contents are valid, fills in the szFormat, fdwSupport, and cbStruct members of ACMFORMATDETAILS.

Before calling the driver’s ACM_IOControl function, the ACM verifies the following conditions:

  • ACMFORMATDETAILS and its associated WAVEFORMATEX structure are readable and writeable.
  • The size of ACMFORMATDETAILS, contained in its cbStruct member, is at least as large as the structure’s defined size. The structure’s size can be larger than its defined size to allow for a longer szFormat member or to enable newer, larger structure definitions to be used within drivers under development.
  • The size of the WAVEFORMATEX structure associated with the pwfx member of ACMFORMATDETAILS is at least as large as the generic WAVEFORMATEX structure’s defined size.
  • The fdwSupport member of ACMFORMATDETAILS contains 0.
  • The lParam2 parameter contains a valid flag value.

The WAVEFORMATEX structure is a generic structure for describing a waveform format. Generally, use this structure as a basis for defining structures for your specific format types, as in the IMA ADPCM audio codec. For an example, see the IMAADPCMWAVEFORMAT structure in the Mmreg.h header file. When a client sends an ACMDM_FORMAT_DETAILS message, it specifies the address of a structure that you have defined for the specified format type. This structure typically is larger than the generic WAVEFORMATEX structure.

Before returning, the driver must set the cbStruct member of ACMFORMATDETAILS to the actual number of bytes returned. The value returned in cbStruct must not be greater than the value received.

The szFormat member of WAVEFORMATEX is used for returning a format description string. If an ACM driver returns a 0-length string in szFormat, the ACM creates an internationalized description string for the format. This string includes the format’s speed (in Hz), bit depth, and channel setting (mono or stereo), based on the contents of the nSamplesPerSec, wBitsPerSample, and nChannels members of WAVEFORMATEX. If wBitsPerSample contains 0, the ACM does not include the bit depth in the description string. You can provide your own description string and return it in szFormat, but it is best to enable the ACM to generate an internationalized description.

For more information about format and filter tags and format and filter structures, see the Windows NT DDK.

See Also

ACMDM_FORMATTAG_DETAILS


ACMDM_FORMAT_SUGGEST

This message requests an ACM driver to choose a preferred destination format for a conversion with a specified source format.

Parameters

dwDriverID
Specifies a driver instance identifier. The driver returns this value in response to the ACM_Open function.
hDriver
Handle to a driver.
uMsg
Specifies this message.
lParam1
Pointer to an ACMDRVFORMATSUGGEST structure. ACMDRVFORMATSUGGEST is declared in the Msacmdrv.h header file.
lParam2
Not used.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR error values declared in the Mmsystem.h header file or one of the ACMERR error values declared in the Msacm.h header file. The following are possible error values:

MMSYSERR_NOTSUPPORTED
The driver does not support format suggestion operations.
ACMERR_NOTPOSSIBLE
The driver cannot suggest a destination format, based on the specified source format and restriction flags.

Remarks

The ACM (Waveapi.dll) sends this message by calling the ACM driver’s ACM_IOControl entry point through the DeviceIoControl function. The ACM sends this message when an application calls the acmFormatSuggest function.

All ACM drivers that provide stream conversions must support this message.

ACMDRVFORMATSUGGEST contains pointers to two WAVEFORMATEX structures. One of these structures describes the client-specified source format. The other structure is used by the driver to return a suggested destination format. The client might specify values for some of the destination structure members in order to restrict the possible suggestions.

Given the specified source format and destination restrictions, if any, the driver determines if it can provide a conversion from the specified source format to a particular destination format. If it can, it returns a description of that format in the destination WAVEFORMATEX structure.

Before calling the driver’s ACM_IOControl function, the ACM should verify the following conditions:

  • The flag values contained in ACMDRVFORMATSUGGEST are valid.
  • The WAVEFORMATEX structure containing the source format description is readable.
  • The WAVEFORMATEX structure specified for receiving the suggested destination format description is writeable.
  • The destination WAVEFORMATEX structure’s size, contained in the cbwfxDst member of ACMDRVFORMATSUGGEST, is large enough to receive a format structure for an appropriate destination format.

See Also

  • ACMDRVFORMATSUGGEST


ACMDM_FORMATTAG_DETAILS

This message requests an ACM driver to return information about a format tag.

Parameters

dwDriverID
Specifies a driver instance identifier. The driver returns this value in response to the ACM_Open function.
hDriver
Handle to a driver.
uMsg
Specifies this message.
lParam1
Pointer to an ACMFORMATTAGDETAILS structure. ACMFORMATTAGDETAILS is declared in the Msacm.h header file.
lParam2
Contains one of the following flags specified by the fdwDetails parameter of the acmFormatTagDetails function:
ACM_FORMATTAGDETAILSF_INDEX
Indicates that the dwFormatTagIndex member of ACMFORMATTAGDETAILS contains a format tag index. The valid index range is from 0 to 1 less than the cFormatTags member returned in the driver’s ACMDRIVERDETAILS structure.

The driver should return details for the format tag associated with the index.

ACM_FORMATTAGDETAILSF_FORMATTAG
Indicates that the dwFormatTag member of ACMFORMATTAGDETAILS contains a format tag.

The driver returns details for the specified format tag.

ACM_FORMATTAGDETAILSF_LARGESTSIZE
Indicates that the driver should return details for the format tag that has the largest format. The dwFormatTag member of ACMFORMATTAGDETAILS can contain a format tag or WAVE_FORMAT_UNKNOWN.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR error values declared in the Mmsystem.h header file or one of the ACMERR error values declared in the Msacm.h header file. The following are possible error values.

MMSYSERR_NOTSUPPORTED
The driver does not support the specified query operation.
ACMERR_NOTPOSSIBLE
The input parameter values do not represent valid formats or format tags.

Remarks

The ACM (Waveapi.dll) sends this message by calling the ACM driver’s ACM_IOControl entry point through the DeviceIoControl function. The ACM sends this message when an application calls the acmFormatTagDetails function.

All ACM drivers must support this message.

The client specifies the format tag in the dwFormatTag member of ACMFORMATTAGDETAILS. The driver returns the following information for a particular tag:

  • If the ACM_FORMATDETAILSF_INDEX flag is set, the client has specified an index value in the dwFormatTagIndex member of ACMFORMATTAGDETAILS. The driver fills in ACMFORMATTAGDETAILS for the format tag associated with the specified index value.
  • If the ACM_FORMATTAGDETAILSF_FORMATTAG flag is set, the client has specified a format tag in the dwFormatTag member of ACMFORMATTAGDETAILS. The driver fills in the ACMFORMATTAGDETAILS for the specified format tag.
  • If the ACM_FORMATTAGDETAILSF_LARGESTSIZE flag is set, the driver performs one of two actions:
    • If dwFormatTag contains WAVE_FORMAT_UNKNOWN, the driver fills in ACMFORMATTAGDETAILS for the format tag that has a format with the largest format structure size.
    • If dwFormatTag contains a format tag, the driver fills in ACMFORMATTAGDETAILS for that format tag, describing the format with the largest structure size belonging to the specified tag.

Before calling the driver’s ACM_IOControl function, the ACM verifies the following conditions:

  • ACMFORMATTAGDETAILS is readable and writeable.
  • The size of ACMFORMATTAGDETAILS, contained in its cbStruct member, is at least as large as the structure’s defined size. The structure’s size can be larger than its defined size, to allow for a longer szFormatTag member or to enable newer, larger structure definitions to be used within drivers under development.
  • The fdwSupport member of ACMFORMATTAGDETAILS contains 0.
  • The lParam2 parameter contains a valid flag value.

If the format tag is WAVE_FORMAT_PCM, the driver return a 0-length string in szFormatTag. The ACM provides a description string for this format.

Before returning, the driver must set the cbStruct member of ACMFORMATTAGDETAILS to the actual number of bytes returned. The value returned in cbStruct must not be greater than the value received.

For more information about format tags and filter tags, see the Windows NT DDK.

See Also

ACMDM_DRIVER_DETAILS


ACMDM_HARDWARE_WAVE_CAPS_INPUT

This message requests an ACM driver to return hardware capabilities for a waveform input device.

Parameters

dwDriverID
Specifies a driver instance identifier. The driver returns this value in response to the ACM_Open function.
hDriver
Handle to a driver.
uMsg
Specifies this message.
lParam1
Pointer to a WAVEINCAPS structure. WAVEINCAPS is declared in the Mmsystem.h header file.
lParam2
Size of the WAVEINCAPS structure pointed to by lParam1.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise the driver returns one of the MMSYSERR error values declared in the Mmsystem.h header file or one of the ACMERR error values declared in the Msacm.h header file. If the driver does not support waveform hardware, it returns MMSYSERR_NOTSUPPORTED.

Remarks

Each time a client calls the acmMetrics function with the ACM_METRIC_HARDWARE_WAVE_INPUT index parameter, the ACM (Waveapi.dll) sends this message by calling the ACM driver’s ACM_IOControl entry point through the DeviceIoControl function..

The driver receives a pointer to a WAVEINCAPS structure. The driver must fill in the structure.

Only ACM drivers that provide access to waveform input hardware need to support this message. If your driver supports this message, it must return ACMDRIVERDETAILS_SUPPORTF_HARDWARE in the ACMDRIVERDETAILS structure provided with the ACMDM_DRIVER_DETAILS message. For more information about providing ACM support, see the Windows NT DDK.


ACMDM_HARDWARE_WAVE_CAPS_OUTPUT

This message requests an ACM driver to return hardware capabilities for a waveform output device.

Parameters

dwDriverID
Specifies a driver instance identifier. The driver returns this value in response to the ACM_Open function.
hDriver
Handle to a driver.
uMsg
Specifies this message.
lParam1
Pointer to a WAVEOUTCAPS structure. The structure is declared in the Mmsystem.h header file.
lParam2
Size of the WAVEOUTCAPS structure pointed to by lParam1.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR error values declared in the Mmsystem.h header file or one of the ACMERR error values declared in the Msacm.h header file. If the driver does not support waveform hardware, it returns MMSYSERR_NOTSUPPORTED.

Remarks

The ACM (Waveapi.dll) sends this message by calling the ACM driver’s ACM_IOControl entry point through the DeviceIoControl function. This call is made each time a client calls the acmMetrics function with the index parameter of ACM_METRIC_HARDWARE_WAVE_OUTPUT.

The driver receives the address of WAVEOUTCAPS and fills in the structure.

Only ACM drivers that provide access to waveform output hardware need to support this message. If your driver supports this message, it must return ACMDRIVERDETAILS_SUPPORTF_HARDWARE in the ACMDRIVERDETAILS structure provided with the ACMDM_DRIVER_DETAILS message. For more information about providing ACM support, see the Windows NT DDK.


ACMDM_STREAM_CLOSE

This message requests an ACM driver to close a conversion stream that was opened with an ACMDM_STREAM_OPEN message.

Parameters

dwDriverID
Specifies a driver instance identifier. The driver returns this value in response to the ACM_Open function.
hDriver
Handle to a driver.
uMsg
Specifies this message.
lParam1
Pointer to an ACMDRVSTREAMINSTANCE structure.
lParam2
Not used.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR error values declared in the Mmsystem.h header file or one of the ACMERR error values declared in the Msacm.h header file. An asynchronous driver might have to return ACMERR_BUSY if a conversion operation has not completed.

Remarks

The ACM (Waveapi.dll) sends this message by calling the ACM driver’s ACM_IOControl entry point through the DeviceIoControl function. The ACM sends this message when an application calls the acmStreamClose function.

All ACM drivers that provide stream conversions must support this message. For more information about stream conversions, see the Windows NT DDK.

If the driver supports asynchronous operations and the client has specified the ACM_STREAMOPENF_ASYNC flag, which is contained in the fdwOpen member of ACMDRVSTREAMINSTANCE, the driver sends the client an MM_ACM_CLOSE callback message. It does this by calling the PostThreadMessage function after the operation completes.


ACMDM_STREAM_CONVERT

This message requests an ACM driver to perform a conversion operation on a specified conversion stream.

Parameters

dwDriverID
Specifies a driver instance identifier. The driver returns this value in response to the ACM_Open function.
hDriver
Handle to a driver.
uMsg
Specifies this message.
lParam1
Pointer to an ACMDRVSTREAMINSTANCE structure.
lParam2
Pointer to an ACMDRVSTREAMHEADER structure.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR error values declared in the Mmsystem.h header file or one of the ACMERR error values declared in the Msacm.h header file.

Remarks

The ACM (Waveapi.dll) sends this message by calling the ACM driver’s ACM_IOControl entry point through the DeviceIoControl function. The ACM sends this message when an application calls the acmStreamConvert function.

All ACM drivers that provide stream conversions must support this message. For more information about stream conversions, see the Windows NT DDK.

The ACMDRVSTREAMINSTANCE structure received with this message is the same structure received with a previous ACMDM_STREAM_OPEN message. The driver does not need to validate the structure’s contents again.

ACMDRVSTREAMHEADER identifies the source and destination data buffers. The source buffer contains the data to be converted. The driver places converted data into the destination buffer.

The driver must check the flags in the fdwConvert member of ACMDRVSTREAMHEADER. These flags indicate how converted data should be returned.

Because stream conversions are time-critical operations, ACMDM_STREAM_CONVERT messages must be processed efficiently. The driver should perform as much processing as possible in response to the ACMDM_STREAM_OPEN message.

If the driver supports asynchronous operations and the client has specified the ACM_STREAMOPENF_ASYNC flag, which is contained in the fdwOpen member of ACMDRVSTREAMINSTANCE, the driver must take the following actions when it has finished converting the data in the source buffer:

  • Set the ACMSTREAMHEADER_STATUSF_DONE flag of ACMDRVSTREAMHEADER.
  • Send the client an MM_ACM_DONE callback message by calling the PostThreadMessage function.

Along with the padshNext member of ACMDRVSTREAMHEADER, asynchronous drivers can use the ACMSTREAMHEADER_STATUSF_INQUEUE flag of the structure to maintain a conversion queue of stream header structures.

Before calling the driver’s ACM_IOControl function, the ACM should verify the following conditions:

  • The structure is readable, writeable, and properly sized.
  • The fdwConvert member of the structure contains valid flag values.
  • The structure’s buffers have been prepared, and the specified buffer sizes are not larger than their prepared sizes.
  • The structure is not currently in an asynchronous driver’s conversion queue; that is, the structure’s ACMSTREAMHEADER_STATUSF_INQUEUE flag is not set.

See Also

ACMDM_STREAM_PREPARE


ACMDM_STREAM_OPEN

This message requests an ACM driver either to open a conversion stream or to indicate whether the specified conversion is supported.

Parameters

dwDriverID
Specifies a driver instance identifier. The driver returns this value in response to the ACM_Open function.
hDriver
Handle to a driver.
uMsg
Specifies this message.
lParam1
Pointer to an ACMDRVSTREAMINSTANCE structure.
lParam2
Not used.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR error values declared in the Mmsystem.h header file or one of the ACMERR error values declared in the Msacm.h header file. If a specified conversion is not supported, the driver should return ACMERR_NOTPOSSIBLE.

Remarks

The ACM (Waveapi.dll) sends this message by calling the ACM driver’s ACM_IOControl entry point through the DeviceIoControl function. The ACM sends this message when an application calls the acmStreamOpen function.

All ACM drivers that provide stream conversions must support this message. For more information about stream conversions, see the Windows NT DDK.

If the client has specified the ACM_STREAMOPENF_QUERY flag, which is contained in the fdwOpen member of ACMDRVSTREAMINSTANCE, the driver should not open a stream instance. The driver returns MMSYSERR_NOERROR if the conversion is possible and MMSYSERR_NOTPOSSIBLE, otherwise.

When a driver receives this message, it first determines if it can perform the specified conversion. If it can, it performs instance initialization operations for the stream, such as determining which conversion routines to use and allocating instance-specific resources.

Store stream instance data in a local, dynamically allocated structure. Store a pointer to the dwDriver member of ACMDRVSTREAMINSTANCE.

If the driver supports asynchronous operations and the client has specified the ACM_STREAMOPENF_ASYNC flag, which is contained in the fdwOpen member of ACMDRVSTREAMINSTANCE, the driver sends the client an MM_ACM_OPEN callback message by calling the PostThreadMessage function after the operation completes.

Before calling the driver’s ACM_IOControl function, the ACM verifies the following conditions:

  • The fdwOpen member of ACMDRVSTREAMINSTANCE contains valid flag values.
  • The source and destination WAVEFORMATEX structures are readable.
  • If a WAVEFILTER structure is specified, it is readable, and the source and destination format structures contain identical information.
  • If the client has specified different source and destination format tags, the driver has declared itself to be a codec by setting ACMDRIVERDETAILS_SUPPORTF_CODEC in the fdwSupport member of ACMDRIVERDETAILS.
  • If the client specifies source and destination formats associated with a single format tag, the driver declares itself to be a converter by setting ACMDRIVERDETAILS_SUPPORTF_CONVERTER in the fdwSupport member of ACMDRIVERDETAILS.
  • If the client specifies a filter operation, the driver declares itself to be a filter by setting ACMDRIVERDETAILS_SUPPORTF_FILTER in the fdwSupport member of ACMDRIVERDETAILS.

If the client specifies the ACM_STREAMOPENF_NONREALTIME flag, which is contained in the fdwOpen member of ACMDRVSTREAMINSTANCE, the driver can perform the conversion without time constraints. However, if this flag is not specified and the driver cannot perform the conversion in real time, it returns ACMERR_NOTPOSSIBLE. For more information about real-time conversions, see the Windows NT DDK.

See Also

ACMDM_DRIVER_DETAILS


ACMDM_STREAM_PREPARE

This message requests an ACM driver to prepare the buffers associated with an ACMDRVSTREAMHEADER structure.

Parameters

dwDriverID
Specifies a driver instance identifier. The driver returns this value in response to the ACM_Open function.
hDriver
Handle to a driver.
uMsg
Specifies this message.
lParam1
Pointer to an ACMDRVSTREAMINSTANCE structure.
lParam2
Pointer to an ACMDRVSTREAMHEADER structure.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR error values declared in the Mmsystem.h header file or one of the ACMERR error values declared in the Msacm.h header file.

Remarks

The ACM (Waveapi.dll) sends this message by calling the ACM driver’s ACM_IOControl entry point through the DeviceIoControl function. The ACM sends this message when an application calls acmStreamPrepareHeader.

Support for this message is optional. However, if a driver supports this message, it must support ACMDM_STREAM_UNPREPARE.

If the driver returns MMSYSERR_NOTSUPPORTED, the ACM prepares the buffers for use. For most drivers, this behavior is sufficient. If the driver performs buffer preparation, it should return MMSYSERR_NOERROR. In either case, the ACM sets ACMSTREAMHEADER_STATUSF_PREPARED in the fdwStatus member of ACMDRVSTREAMHEADER. The driver never modifies this flag. If you want both your driver and the ACM to perform buffer preparation operations, the driver should return MMSYSERR_NOTSUPPORTED after performing its preparation activity. The ACM then can perform its preparation operation.

Before calling the driver’s ACM_IOControl function, the ACM verifies the following conditions:

  • ACMDRVSTREAMHEADER is readable and writeable.
  • The cbStruct member of ACMDRVSTREAMHEADER contains a size value that is at least as large as the structure’s defined size.
  • The specified buffers have not already been prepared.

For more information about the use of this message, see the Windows NT DDK.


ACMDM_STREAM_RESET

This message requests an ACM driver to stop conversion operations for the specified stream.

Parameters

dwDriverID
Specifies a driver instance identifier. The driver returns this value in response to the ACM_Open function.
hDriver
Handle to a driver.
uMsg
Specifies this message.
lParam1
Pointer to an ACMDRVSTREAMINSTANCE structure.
lParam2
Contains the fdwReset parameter of the acmStreamReset function.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR error values declared in the Mmsystem.h header file or one of the ACMERR error values declared in the Msacm.h header file.

Remarks

The ACM (Waveapi.dll) sends the ACMDM_STREAM_RESET message by calling the ACM driver’s ACM_IOControl entry point through the DeviceIoControl function. The ACM sends this message when an application calls the acmStreamReset function.

Only asynchronous drivers receive this message. If a client calls acmStreamReset for a synchronous driver, the ACM returns MMSYSERR_NOERROR without calling the driver.

When an asynchronous driver receives this message, it sets the ACMSTREAMHEADER_STATUSF_DONE flag and clears the ACMSTREAMHEADER_STATUSF_INQUEUE flag in every ACMDRVSTREAMHEADER structure contained in its conversion queue.

For more information about stream conversions, see the Windows NT DDK.


ACMDM_STREAM_SIZE

This message requests an ACM driver to return the size required for a source or destination buffer with a specified destination or source buffer size, along with source and destination format descriptions.

Parameters

dwDriverID
Specifies a driver instance identifier. The driver returns this value in response to the ACM_Open function.
hDriver
Handle to a driver.
uMsg
Specifies this message.
lParam1
Pointer to an ACMDRVSTREAMINSTANCE structure.
lParam2
Pointer to an ACMDRVSTREAMSIZE structure.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR error values declared in the Mmsystem.h header file or one of the ACMERR error values declared in the Msacm.h header file.

Remarks

The ACM (Waveapi.dll) sends the ACMDM_STREAM_SIZE message by calling the ACM driver’s ACM_IOControl entry point through the DeviceIoControl function. The ACM sends this message when an application calls the acmStreamSize function.

All ACM drivers that provide stream conversions must support this message. For more information about stream conversions, see the Windows NT DDK.

Based on the input parameters, the driver must return the following information:

  • How large the destination buffer must be in order to hold all the converted data for a source buffer of a specified size.
  • The largest amount of source data that will not overflow such a destination buffer.

The ACMDRVSTREAMINSTANCE structure received with this message is the same structure that was received with a previous ACMDM_STREAM_OPEN message. The driver does not need to validate the structure’s contents again.

The driver examines ACMDRVSTREAMSIZE to determine which buffer, source, or destination the client has supplied. ACMDRVSTREAMINSTANCE contains structures that describe the source and destination formats and possibly a filter specification. The driver uses this information to determine the size of the requested buffer.

If the driver returns a buffer length of 0, the ACM provides an error return value of ACMERR_NOTPOSSIBLE to acmStreamSize.


ACMDM_STREAM_UNPREPARE

This message requests an ACM driver to clear the preparation of the buffers associated with an ACMDRVSTREAMHEADER structure.

Parameters

dwDriverID
Specifies a driver instance identifier. The driver returns this value in response to the ACM_Open function.
hDriver
Handle to a driver.
uMsg
Specifies this message.
lParam1
Pointer to an ACMDRVSTREAMINSTANCE structure.
lParam2
Pointer to an ACMDRVSTREAMHEADER structure.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR error values declared in the Mmsystem.h header file or one of the ACMERR error values declared in the Msacm.h header file.

Remarks

The ACM (Waveapi.dll) sends this message by calling the ACM driver’s ACM_IOControl entry point through the DeviceIoControl function. The ACM sends this message when an application calls the acmStreamUnprepareHeader function.

Support for this message is optional. However, if a driver supports ACMDM_STREAM_PREPARE, it must support this message.

If the driver returns MMSYSERR_NOTSUPPORTED, the ACM clears the buffer preparation. For most drivers, this behavior is sufficient. If the driver does clear buffer preparation, it returns MMSYSERR_NOERROR. In either case, the ACM clears ACMSTREAMHEADER_STATUSF_PREPARED in the fdwStatus member of ACMDRVSTREAMHEADER. The driver never modifies this flag. If you want both your driver and the ACM to clear buffer preparations, the driver returns MMSYSERR_NOTSUPPORTED after clearing its preparation. The ACM can then clear its preparation.

Before calling the driver’s ACM_IOControl function, the ACM verifies the following conditions:

  • ACMDRVSTREAMHEADER is readable and writeable.
  • The cbStruct member of the structure contains a size value that is at least as large as the structure’s defined size.
  • The buffers have been previously prepared.
  • The buffer addresses and sizes match those specified when the buffers were prepared.
  • The buffers are not currently in use by an asynchronous driver, based on the ACMSTREAMHEADER_STATUSF_INQUEUE flag value of the structure.

For more information about ACMDM_STREAM_UNPREPARE, see the Windows NT DDK.


WIDM_ADDBUFFER

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform input driver to add an empty input buffer to its input buffer queue.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Pointer to a WAVEHDR structure identifying the buffer.
dwParam2
Size, in bytes, of WAVEHDR.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVERR error values declared in the Mmsystem.h header file.

Remarks

The ACM (Waveapi.dll) sends the WIDM_ADDBUFFER message by calling the audio driver’s (Wavedev.dll) WAV_IOControl entry point through the DeviceIoControl function.

If the WHDR_PREPARED flag is not set in the dwFlags member of WAVEHDR, the driver returns WAVERR_UNPREPARED. If the flag is set, the driver performs the following actions:

  • Clears the WHDR_DONE flag.
  • Sets the WHDR_INQUEUE flag.
  • Places the empty buffer in its input queue.
  • Returns with a value of MMSYSERR_NOERROR.

The driver starts recording when it receives a WIDM_START message.


WIDM_CLOSE

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform input driver to close a specified device instance previously opened with WIDM_OPEN.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Not used.
dwParam2
Not used.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVERR error values declared in the Mmsystem.h header file.

Remarks

The ACM (Waveapi.dll) sends the WIDM_CLOSE message by calling the audio driver’s (Wavedev.dll) WAV_IOControl entry point through the DeviceIoControl function.

If the driver has not filled and returned all the buffers received with WIDM_ADDBUFFER messages, it does not close the instance. Instead, it returns WAVERR_STILLPLAYING.

After the driver closes the device instance, it sends a WIM_CLOSE callback message to the ACM.


WIDM_GETDEVCAPS

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform input driver to return the capabilities of a specified device.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Specifies a pointer to a WAVEINCAPS structure.
dwParam2
Size, in bytes, of WAVEINCAPS.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.


WIDM_GETNUMDEVS

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform input driver to return the number of device instances that it supports.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Not used.
dwParam2
Not used.

Return Values

The driver returns the number of waveform input device instances it supports. The default audio driver's MDD layer returns 1.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.


WIDM_GETPOS

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform input driver to return the current input position within a waveform. The input position is relative to the first recorded sample of the waveform.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Specifies a pointer to an MMTIME structure.
dwParam2
Specifies the size, in bytes, of MMTIME.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.

The wType member of MMTIME indicates the time format requested by the client. If the driver cannot support the requested format, it returns the position in a format that it does support and changes the wType member accordingly.

The position is reset to 0 when the driver receives either of the messages WODM_OPEN or WODM_RESET.


WIDM_OPEN

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform input driver to open an instance of a specified device.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a pointer to a location to receive the device instance identifier.
dwParam1
Specifies a pointer to a WAVEOPENDESC structure containing the client’s device handle, notification target, and instance identifier.
dwParam2
Contains one or both of the following flags:
WAVE_FORMAT_DIRECT
Data compression and decompression should take place in hardware.
WAVE_FORMAT_QUERY
The driver indicates whether or not it supports the specified format.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the error values MMSYSERR or WAVERR declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.

The driver assigns a device instance identifier and returns it in the location pointed to by the parameter dwUser. The driver receives this value as the input parameter dwUser to all other wave input driver messages.

The driver determines the number of clients that it enables to use a particular device. If a device is opened by the maximum number of clients, it returns MMSYSERR_ALLOCATED for subsequent open requests.

The flag WAVE_FORMAT_DIRECT is meant for use with a wave mapper. If the flag is set in dwParam2, the driver does not call the ACM to handle compression and decompression operations—the caller sets that flag to indicate that the driver uses the hardware to perform these operations directly. If the hardware is not capable of performing the operations, the driver returns MMSYSERR_NOTSUPPORTED when WAVE_FORMAT_DIRECT is set.

If the WAVE_FORMAT_QUERY flag is set in dwParam2, the driver does not open the device. Instead, it determines whether it supports the format specified by the lpFormat member of WAVEOPENDESC. If the driver supports the requested format, it returns MMSYSERR_NOERROR. Otherwise, the driver returns WAVERR_BADFORMAT.

If the open operation succeeds, the Wave API Manager sends the ACM the WIM_OPEN message by calling the PostThreadMessage function on the callback thread handle.


WIDM_PREPARE

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform input driver to prepare a system-exclusive data buffer for input.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Specifies a pointer to a WAVEHDR structure identifying the buffer.
dwParam2
Specifies the size, in bytes, of WAVEHDR.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVEERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.

Support for this message by drivers is optional. However, if the driver supports this message, it must support WIDM_UNPREPARE.

If the driver returns MMSYSERR_NOTSUPPORTED, Waveapi.dll prepares the buffer for use. For most drivers, this behavior is sufficient. If the driver performs buffer preparation, it must set WHDR_PREPARED in the dwFlags member of WAVEHDR and return MMSYSERR_NOERROR.


WIDM_RESET

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform input driver to stop recording and return all buffers in the input queue to the caller.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Not used.
dwParam2
Not used.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.

For each buffer remaining in the driver’s input queue, the driver sets WHDR_DONE and clears WHDR_INQUEUE in the dwFlags member of the buffer’s WAVEHDR structure. It also sets the dwBytesRecorded member of the structure. Finally, the driver issues the callback message WIM_DATA for each buffer.

See Also

WIDM_ADDBUFFER


WIDM_START

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform input driver to begin recording.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Not used.
dwParam2
Not used.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.


WIDM_STOP

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform input driver to stop recording.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Not used.
dwParam2
Not used.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.

If a buffer in the input queue has been partially filled, the driver treats it as a full buffer and returns it to the client. Empty buffers remain in the queue.

If this message is received and recording is already stopped, the driver returns MMSYSERR_NOERROR.

See Also

WIDM_ADDBUFFER, WIDM_START


WIDM_UNPREPARE

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform input driver to undo the buffer preparation that was performed in response to a WIDM_PREPARE message.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
UMsg
Specifies this message.
DwUser
Specifies a device instance identifier.
DwParam1
Pointer to a WAVEHDR structure identifying the buffer.
DwParam2
Specifies the size, in bytes, of WAVEHDR.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.

Support for this message by user-mode drivers is optional. However, if the driver supports WIDM_PREPARE, it must support this message.

If the driver returns MMSYSERR_NOTSUPPORTED, the ACM removes the buffer preparation. For most drivers, this behavior is sufficient. If the driver supports WODM_UNPREPARE, it must clear WHDR_PREPARED in the dwFlags member of WAVEHDR and return MMSYSERR_NOERROR.


WODM_BREAKLOOP

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform output driver to break an output loop that was created with a WODM_WRITE message.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Not used.
dwParam2
Not used.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends the WODM_BREAKLOOP message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.

The driver should stop output of the loop buffers at the end of the next loop iteration.

If the driver receives this message and a loop is not in progress, it returns MMSYSERR_NOERROR.


WODM_CLOSE

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform output driver to close a specified device instance that was previously opened with a WODM_OPEN message.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Not used.
dwParam2
Not used.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.

If the client has passed data buffers to the driver by means of WODM_WRITE messages and the driver has not finished sending the data to the PDD, the driver returns WAVERR_STILLPLAYING in response to this message.

After the driver closes the device instance, it sends a WOM_CLOSE callback message to the ACM.


WODM_GETDEVCAPS

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform output driver to return the capabilities of a specified device.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Specifies a pointer to a WAVEOUTCAPS structure.
dwParam2
Specifies the size, in bytes, of WAVEOUTCAPS.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.


WODM_GETNUMDEVS

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform output driver to return the number of device instances that it supports.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Not used.
dwParam2
Not used.

Return Values

The driver returns the number of waveform output device instances it supports. For Windows CE, the default MDD returns 1.

Remarks

The ACM sends the WODM_GETNUMDEVS message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.


WODM_GETPITCH

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform output driver to return the specified device’s current pitch multiplier value.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Specifies a pointer to a DWORD location used to return the current pitch multiplier value. This is specified as a fixed-point value, where the high-order WORD of the DWORD contains the signed integer part of the number and the low-order WORD contains the fractional part. The fraction consists of a WORD value, for which 0x8000 represents one half and 0x4000 represents one-fourth. For example, the value 0x00010000 specifies a multiplier of 1.0, with no pitch change, and a value of 0x000F8000 specifies a multiplier of 15.5.
dwParam2
Not used.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.

Support for this message by drivers is optional. However, if a driver supports the WODM_SETPITCH message, it must support this message.


WODM_GETPLAYBACKRATE

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform output driver to return the current playback rate multiplier value for the specified device.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Specifies a pointer to a DWORD location used to return the current playback rate multiplier value. This is specified as a fixed-point value, where the high-order WORD of the DWORD contains the signed integer part of the number and the low-order WORD contains the fractional part. The fraction consists of a WORD value, for which 0x8000 represents one half and 0x4000 represents one-fourth. For example, the value 0x00010000 specifies a multiplier of 1.0, with no pitch change, and a value of 0x000F8000 specifies a multiplier of 15.5.
dwParam2
Not used.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.

Support for this message by drivers is optional. However, if a driver supports the WODM_SETPLAYBACKRATE message, it must support this message.


WODM_GETPOS

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform output driver to return the current position within a waveform. The position is relative to the beginning of the waveform.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Specifies a pointer to an MMTIME structure, which is described in the Microsoft Windows CE Platform SDK.
dwParam2
Specifies the size, in bytes, of MMTIME.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.

The wType member of MMTIME indicates the time format requested by the client. If the driver cannot support the requested format, it returns the position in a format that it supports and changes the wType member accordingly.

The position is reset to 0 when the driver receives a WODM_OPEN or WODM_RESET message.


WODM_GETVOLUME

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform output driver to return the current volume level setting for the specified device.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this structure.
dwUser
Specifies a device instance identifier.
dwParam1
Pointer to a DWORD location to receive the volume setting.
dwParam2
Not used.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function. Support for this message by drivers is optional. However, if the driver supports WODM_SETVOLUME, it must support this message. The following table shows which bytes in dwParam1 indicate the volume settings for both stereo and monaural audio channels.

Channel
Portion of dwParam1 Used
Left Channel | Low word
Right Channel | High word
Single Channel | Low word

A value of 0 is silence, and a value of 0xFFFF is full volume.


WODM_OPEN

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform output driver to open an instance of a specified device.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Pointer to a location to receive the device instance identifier.
dwParam1
Pointer to a WAVEOPENDESC structure containing the client’s device handle, notification target, and instance identifier
dwParam2
Contains the following flags:
WAVE_FORMAT_DIRECT
Data compression and decompression take place in hardware.
WAVE_FORMAT_QUERY
The driver indicates whether or not it supports the specified format.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVEERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.

The driver assigns a device instance identifier and returns it in the location pointed to by dwUser. The driver receives this value as the dwUser input parameter to all other wave output driver messages.

The driver determines the number of clients that it enables to use a particular device. If a device is opened by the maximum number of clients, the driver returns MMSYSERR_ALLOCATED for subsequent open requests.

The WAVE_FORMAT_DIRECT flag is meant for use with a wave mapper. If the flag is set in dwParam2, the driver does not call the ACM to handle compression or decompression operations; the caller wants the hardware to perform these operations directly. If the hardware is not capable of performing compression or decompression operations, the driver returns MMSYSERR_NOTSUPPORTED when WAVE_FORMAT_DIRECT is set.

If the WAVE_FORMAT_QUERY flag is set in dwParam2, the driver does not open the device. Instead, the driver determines whether it supports the format specified by the lpFormat member of WAVEOPENDESC. If the driver supports the requested format, it returns MMSYSERR_NOERROR. Otherwise, the driver returns WAVERR_BADFORMAT.

If the open operation succeeds, the Wave API Manager sends the ACM a WOM_OPEN message by calling the PostThreadMessage function on the callback thread handle.


WODM_PAUSE

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform output driver to pause playback of a waveform.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Not used.
dwParam2
Not used.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVEERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.

The driver stops playing the waveform and saves the current position. Playback continues from this position when the driver receives a WODM_RESTART message. The driver places any output buffers received with the WODM_WRITE message while playback is paused in the output queue.

If the driver receives this message when output is already paused, it returns MMSYSERR_NOERROR.


WODM_PREPARE

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform output driver to prepare a system-exclusive data buffer for output.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Specifies a pointer to a WAVEHDR structure identifying the buffer.
dwParam2
Specifies the size, in bytes, of WAVEHDR.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVEERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.

Support for this message by drivers is optional. However, if the driver supports this message, it must support WODM_UNPREPARE.

If the driver returns MMSYSERR_NOTSUPPORTED, Waveapi.dll prepares the buffer for use. For most drivers, this behavior is sufficient. If the driver does perform buffer preparation, it must set WHDR_PREPARED in the dwFlags member of WAVEHDR and return MMSYSERR_NOERROR.


WODM_RESET

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform output driver to stop sending output data and return all output buffers to the list.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Not used.
dwParam2
Not used.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVEERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.

If the driver’s output queue contains any output buffers whose contents have not been played, the driver sets the WHDR_DONE flag and clears the WDR_INQUEUE flag in each buffer’s WAVEHDR structure. The driver then sends the ACM a WOM_DONE callback message for each buffer.

The driver should reset its position count to 0. If playback is paused, the driver takes itself out of the paused state.

See Also

WODM_WRITE


WODM_RESTART

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform output driver to continue playback of a waveform after playback has been paused with WODM_PAUSE.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Not used.
dwParam2
Not used.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVEERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.

Data output resumes from the position that was saved when the WODM_PAUSE message was received.

If the driver receives this message and output is not in a paused state, the driver does nothing except return MMSYSERR_NOERROR.


WODM_SETPITCH

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform output driver to set the specified device’s pitch multiplier value.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
A DWORD containing the pitch multiplier value. This is specified as a fixed-point value, where the high-order WORD of the DWORD contains the signed integer part of the number and the low-order WORD contains the fractional part. The fraction consists of a WORD value, for which 0x8000 represents one-half and 0x4000 represents one-fourth. For example, the value 0x00010000 specifies a multiplier of 1.0, with no pitch change, and a value of 0x000F8000 specifies a multiplier of 15.5.
dwParam2
Not used.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVEERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.

Support for this message by drivers is optional. However, if a driver supports this message, it must support WODM_GETPITCH. Additionally, in response to a WODM_GETDEVCAPS message, it must set WAVECAPS_PITCH in the dwSupport member of the WAVEOUTCAPS structure.


WODM_SETPLAYBACKRATE

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform output driver to set the playback rate multiplier value for the specified device.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
A DWORD containing the playback rate multiplier value. This is specified as a fixed-point value, where the high-order WORD of the DWORD contains the signed integer part of the number and the low-order WORD contains the fractional part. The fraction consists of a WORD value, for which 0x8000 represents one-half and 0x4000 represents one-fourth. For example, the value 0x00010000 specifies a multiplier of 1.0, with no rate change, and a value of 0x000F8000 specifies a multiplier of 15.5.
dwParam2
Not used.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVEERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.

Support for this message by drivers is optional. However, if a driver supports this message, it must support WODM_GETPLAYBACKRATE. Additionally, in response to the WODM_GETDEVCAPS message, it must set WAVECAPS_PLAYBACKRATE in the dwSupport member of the WAVEOUTCAPS structure.


WODM_SETVOLUME

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform output driver to set the playback rate multiplier value for the specified device.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Specifies a DWORD containing the volume setting.
dwParam2
Not used.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVEERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function. Support for this message by drivers is optional. However, if the driver supports this message, it must support WODM_GETVOLUME. The following table shows which bytes in dwParam1 indicate the volume settings for both stereo and monaural audio channels.

Channel
Portion of dwParam1 Used
Left Channel | Low word
Right Channel | High word
Single Channel | Low word

A value of 0 is silence, 0xFFFF is full volume.


WODM_UNPREPARE

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform output driver to remove the buffer preparation performed in response to WODM_PREPARE.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Specifies a pointer to a WAVEHDR structure identifying the buffer.
dwParam2
Specifies the size, in bytes, of WAVEHDR.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVEERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.

Support for this message by user-mode drivers is optional. However, if the driver supports WODM_PREPARE, it must support this message.

If the driver returns MMSYSERR_NOTSUPPORTED, the ACM removes the buffer preparation. For most drivers, this behavior is sufficient. If the driver does support this message, it must clear WHDR_PREPARED in the dwFlags member of WAVEHDR and return MMSYSERR_NOERROR.


WODM_WRITE

This message is used in an MMDRV_MESSAGE_PARAMS structure passed to the WAV_IOControl function to request a waveform output driver to write a waveform data block to the specified device.

Parameters

uDeviceId
Device identifier—0, 1, 2, and so on—for the target device.
uMsg
Specifies this message.
dwUser
Specifies a device instance identifier.
dwParam1
Pointer to a WAVEHDR structure identifying the buffer.
dwParam2
Specifies the size, in bytes, of WAVEHDR.

Return Values

MMSYSERR_NOERROR indicates success. Otherwise, the driver returns one of the MMSYSERR or WAVEERR error values declared in the Mmsystem.h header file.

Remarks

The ACM sends this message by calling the audio driver’s WAV_IOControl entry point through the DeviceIoControl function.

If the WHDR_PREPARED flag in the dwFlags member of WAVEHDR is not set, the driver returns WAVERR_UNPREPARED.

Unless the device has been paused with a WODM_PAUSE message, the driver begins playback the first time it receives this message.

Waveform output drivers handle output asynchronously by creating a separate thread to handle communication with the hardware. Typically, the original thread queues the output buffer, sets its WHDR_INQUEUE flag, clears its WHDR_DONE flag in WAVEHDR, and returns control to the client.

The driver continues sending buffers to the audio circuit until the client sends WODM_PAUSE or WIDM_RESET.

The driver usually is responsible for implementing waveform looping. The driver should check each buffer’s WAVEHDR structure for WHDR_BEGINLOOP and WHDR_ENDLOOP flags, along with an iteration count in the dwLoops member of the structure.


WPDM_CLOSE

This message is passed to the PDD_WaveProc function to instruct the audio PDD that the driver’s wave XXX Close function has been called.

Parameters

apidir
Input and output; one of the following values:
WAPI_IN
Closes input path.
WAPI_OUT
Closes output path.
dwParam1
Not used.
dwParam2
Not used.

Remarks

This message enables the PDD to undo, if necessary, any setup that took place in WPDM_OPEN.

This message is declared in the Waveddsi.h header file.

See Also

PDD_WaveProc


WPDM_CONTINUE

This message is passed to the PDD_WaveProc function to instruct the audio PDD to continue with the data pointed to by the wave header.

Parameters

apidir
Input and output; one of the following values:
WAPI_IN
Continue recording.
WAPI_OUT
Continue playback.
dwParam1
Specifies a pointer to the head of a list of WAVEHDR structures.
dwParam2
Not used.

Remarks

This message is declared in the Waveddsi.h header file.

See Also

PDD_WaveProc


WPDM_ENDOFDATA

This message is passed to the PDD_WaveProc function to instruct the audio PDD that no more output data is available and that the audio circuit should finish playing the data blocks already received.

Parameters

apidir
Output only. One of the following values:
WAPI_IN
Not used.
WAPI_OUT
Support required for output.
dwParam1
Not used.
dwParam2
Not used.

Remarks

After the driver processes this message, the hardware generates one more interrupt of type AUDIO_STATE_OUT_STOPPED to indicate that this function completed asynchronously.

This message is declared in the Waveddsi.h header file.

See Also

PDD_WaveProc


WPDM_GETDEVCAPS

This message is passed to the PDD_WaveProc function to instruct the audio PDD to query the hardware to determine its capabilities.

Parameters

apidir
Input and output; one of the following values:
WAPI_IN
Obtain input capabilities.
WAPI_OUT
Obtain output capabilities.
dwParam1
Pointer to a WAVEOUTCAPS structure that holds information about capabilities. If this parameter is NULL, the PDD returns immediately, indicating whether the driver supports the specified direction of data transfer. For example, if apidir is WAPI_IN, and input is not supported, this function returns MMSYSERR_NOTSUPPORTED.
dwParam2
Specifies the size, in bytes, of WAVEOUTCAPS.

Remarks

This message is declared in the Waveddsi.h header file.

See Also

PDD_WaveProc


WPDM_GETVOLUME

This message is passed to the PDD_WaveProc function to instruct the audio PDD to query the current volume setting of the audio device.

Parameters

apidir
Output only; one of the following values:
WAPI_IN
Not used.
WAPI_OUT
See the waveOutGetVolume function in the Windows CE Platform SDK.
dwParam1
Pointer to a DWORD location to receive the volume setting. For a description of volume format, see the waveOutSetVolume function in the Platform Builder.
dwParam2
Not used.

Remarks

This message is declared in the Waveddsi.h header file.

See Also

PDD_WaveProc


WPDM_OPEN

This message is passed to the PDD_WaveProc function to instruct the audio PDD to indicate that the waveform device will be sent data of the specified format.

Parameters

apidir
Input and output; one of the following values
WAPI_IN
Opens input path.
WAPI_OUT
Opens output path.
dwParam1
Pointer to a WAVEFORMATEX structure that points to the format of the data to be played.
dwParam2
BOOL. TRUE indicates that the driver needs to check only if the specified format is supported. If the format is not supported, the driver returns WAVEERR_BADFORMAT. FALSE indicates that this WPDM_OPEN message is a genuine open request.

Remarks

This message is declared in the Waveddsi.h header file.

See Also

PDD_WaveProc


WPDM_PAUSE

This message is passed to the PDD_WaveProc function to instruct the audio PDD to pause playback.

Parameters

apidir
Output only; one of the following values:
WAPI_IN
Not used.
WAPI_OUT
Support required for output.
dwParam1
Not used.
dwParam2
Not used.

Remarks

This message is declared in the Waveddsi.h header file.

See Also

PDD_WaveProc


WPDM_RESTART

This message is passed to the PDD_WaveProc function to instruct the audio PDD to continue playing the paused data.

Parameters

apidir
Output only; one of the following values:
WAPI_IN
Not used.
WAPI_OUT
Support required for output.
dwParam1
Pointer to the head of a list of WAVEHDR structures.
dwParam2
Not used.

Remarks

This message is declared in the Waveddsi.h header file.

See Also

PDD_WaveProc


WPDM_SETVOLUME

This message is passed to the PDD_WaveProc function to instruct the audio PDD to modify the current volume setting of the audio device.

Parameters

apidir
Output only; one of the following values:
WAPI_IN
Not used.
WAPI_OUT
See the waveOutSetVolume function in the Windows CE Platform SDK.
dwParam1
Specifies a volume to which to set the audio device.
dwParam2
Not used.

Remarks

This message is declared in the Waveddsi.h header file.

See Also

PDD_WaveProc


WPDM_STANDBY

This message is passed to the PDD_WaveProc function to instruct the audio PDD to put the audio circuitry in standby mode.

Parameters

apidir
Input and output; one of the following values:
WAPI_IN
Puts input circuitry in standby.
WAPI_OUT
Puts output circuitry in standby.
dwParam1
Not used.
dwParam2
Not used.

Remarks

This message should turn off as much of the audio circuit as possible. When this message is called again, the audio circuitry should be turned on as quickly as possibly. This message is sent between playback of sounds in order to minimize audio circuit power drain.

This message is declared in the Waveddsi.h header file.

See Also

PDD_WaveProc


WPDM_START

This message is passed to the PDD_WaveProc function to instruct the audio PDD to start with the data pointed to by the wave header.

Parameters

apidir
Input and output; one of the following values:
WAPI_IN
Start recording into the specified buffers.
WAPI_OUT
Start playback of the specified buffers.
dwParam1
Pointer to the head of a list of WAVEHDR structures.
dwParam2
Not used.

Remarks

This message is declared in the Waveddsi.h header file.

See Also

PDD_WaveProc


WPDM_STOP

This message is passed to the PDD_WaveProc function to instruct the audio PDD to stop playback or recording immediately.

Parameters

apidir
Input and output; one of the following values:
WAPI_IN
Start recording into the specified buffers.
WAPI_OUT
Start playback of the specified buffers.
dwParam1
Pointer to the head of a list of WAVEHDR structures.
dwParam2
Not used.

Remarks

This message is declared in the Waveddsi.h header file.

See Also

PDD_WaveProc


Constants

This section contains information about constants associated with various types of device driver. Your drivers can use these codes to identify and act on a variety of events and conditions that are defined in Windows CE.


PC Card Event Codes

This section lists the event codes that Card Services sends to the stream interface driver’s callback function to indicate that a PC Card event has occurred. Not all option codes are supported on all Windows CE–based platforms. The following table shows the defined codes.

Event code
Meaning
CE_BATTERY_DEAD | Indicates a dead battery on the PC Card. This event is signaled through the BVD1 pin, which can also be accessed through the pin replacement register (PRR).
CE_BATTERY_LOW | Indicates a low battery on the PC Card. This event is signaled through the BVD2 pin, which can also be accessed through the PRR.
CE_CARD_LOCK | Indicates that the mechanical card lock is closed.
CE_CARD_READY | Indicates that a PC Card has changed from a busy to a ready state.
CE_CARD_REMOVAL | Indicates that a PC Card has been removed from the socket.
CE_CARD_UNLOCK | Indicates that the mechanical card lock is open.
CE_PM_RESUME | Indicates that the system has resumed after being turned off and is now running.
CE_EXCLUSIVE_COMPLETE | Indicates that a driver’s CardRequestExclusive request has taken place.
CE_EXCLUSIVE_REQUEST | Indicates that a driver has called CardRequestExclusive with a request for exclusive access to a PC Card.
CE_WRITE_PROTECT | Indicates that a PC Card’s write-protect status has changed.
CE_CARD_INSERTION | Indicates that a PC Card has been inserted in the socket. Applications registering for insertion events also receive this event for cards that are already in the socket after a suspend or resume event.
CE_REGISTRATION_COMPLETE | Indicates that client registration is complete.


PC Card Event Masks

Event masks specify which events cause a client callback. The following table shows the defined masks.

Event mask
Meaning
EVENT_MASK_WRITE_PROTECT | Write-protect state
EVENT_MASK_CARD_LOCK | Card lock state
EVENT_MASK_EJECT_REQ | Ejection request
EVENT_MASK_INSERT_REQ | Insertion request
EVENT_MASK_BATTERY_DEAD | Battery dead
EVENT_MASK_BATTERY_LOW | Battery low
EVENT_MASK_CARD_READY | Ready change
EVENT_MASK_CARD_DETECT | Card detect
EVENT_MASK_POWER_MGMT | Power management change
EVENT_MASK_RESET | Card reset
EVENT_MASK_STATUS_CHANGE | Card-generated status change interrupt


PC Card Tuple Codes

Tuple codes identify tuples in the tuple chain in a PC Card’s card information structure. The following table shows the defined tuple codes.

Tuple type
Purpose
CISTPL_ALTSTR | Alternate language string tuple.
CISTPL_BATTERY | Battery replacement data tuple.
CISTPL_BYTEORDER | Byte order tuple.
CISTPL_CFTABLE_ENTRY | Configuration tuple entry.
CISTPL_CFTABLE_ENTRY_CB | Configuration table entry tuple for cardbus function.
CISTPL_CHECKSUM | Checksum control tuple. Contains checksum for a specified area of CIS.
CISTPL_CONFIG | Configuration tuple.
CISTPL_CONFIG_CB | Configuration tuple for cardbus function.
CISTPL_DATE | Card initialization data tuple.
CISTPL_DEVICE | Device information tuple for common memory. Describes the parameters for the memory devices in common memory.
CISTPL_DEVICE_A | Device information tuple for attribute memory. Describes the parameters for the memory devices in attribute memory.
CISTPL_DEVICE_OA | Operating conditions for attribute memory.
CISTPL_DEVICE_OC | Operating conditions for common memory.
CISTPL_END | End of tuple chain.
CISTPL_FORMAT | Data recording format.
CISTPL_FUNCE | Function extension tuple.
CISTPL_FUNCID | Function identification tuple.
CISTPL_GEODEVICE | Device geometry information tuple for common memory.
CISTPL_GEODEVICE_A | Device geometry information tuple for attribute memory.
CISTPL_GEOMETRY | Geometry tuple.
CISTPL_JEDEC_A | JEDEC identifier for attribute memory.
CISTPL_JEDEC_C | JEDEC identifier for common memory.
CISTPL_LINKTARGET | Long link target control tuple.
CISTPL_LONG_LINK_MFC | Long link control tuple for multiple function 16-bit PC Card.
CISTPL_LONGLINK_A | Long link control tuple for attribute memory.
CISTPL_LONGLINK_C | Long link control tuple for common memory.
CISTPL_LONGLINK_CB | Long link control tuple for cardbus cards.
CISTPL_LONGLINK_MFC | Multiple function.
CISTPL_MANFID | Manufacturer’s ID tuple.
CISTPL_NO_LINK | No link control tuple. Drivers should ignore all long links in this chain.
CISTPL_NULL | Null tuple. Ignore this tuple.
CISTPL_ORG | Organization tuple.
CISTPL_VERS_1 | Level 1 version tuple.
CISTPL_VERS_2 | Level 2 version tuple.


PC Card Window Attributes

Window attribute masks define memory or I/O window configurations. The following table shows the defined window attribute masks.

Attribute mask
Attribute meaning
WIN_ATTR_IO_SPACE | 1 = I/O window; 0 = memory window
WIN_ATTR_ATTRIBUTE | 1 = attribute; 0 = common
WIN_ATTR_ENABLED | 1 = window enabled; 0 = window disabled
WIN_ATTR_16BIT | 1 = 16 bit; 0 = 8 bit
WIN_ATTR_PAGED | 1 = size is 16 KB multiple
WIN_ATTR_SHARED | 1 = shared memory request
WIN_ATTR_FIRST_SHARED | 1 = first shared request
WIN_ATTR_OFFSETS_SIZED | Card offsets window sized
WIN_ATTR_ACCESS_SPEED_VALID | Causes window’s access speed to change


PC Card Window Speeds

Window speed masks specify the access speed for a memory or I/O window. The following table shows the defined window speed masks.

Speed mask
Value
WIN_SPEED_EXP_MASK | Exponent mask
WIN_SPEED_EXP_1NS | 1 nanosecond
WIN_SPEED_EXP_10NS | 10 nanoseconds
WIN_SPEED_EXP_100NS | 100 nanoseconds
WIN_SPEED_EXP_1US | 1 microsecond
WIN_SPEED_EXP_10US | 10 microseconds
WIN_SPEED_EXP_100US | 100 microseconds
WIN_SPEED_EXP_1MS | 1 millisecond
WIN_SPEED_EXP_10MS | 10 milliseconds
WIN_SPEED_MANT_MASK | Mantissa mask
WIN_SPEED_MANT_10 | 1.0
WIN_SPEED_MANT_12 | 1.2
WIN_SPEED_MANT_13 | 1.3
WIN_SPEED_MANT_15 | 1.5
WIN_SPEED_MANT_20 | 2.0
WIN_SPEED_MANT_25 | 2.5
WIN_SPEED_MANT_30 | 3.0
WIN_SPEED_MANT_35 | 3.5
WIN_SPEED_MANT_40 | 4.0
WIN_SPEED_MANT_45 | 4.5
WIN_SPEED_MANT_50 | 5.0
WIN_SPEED_MANT_55 | 5.5
WIN_SPEED_MANT_60 | 6.0
WIN_SPEED_MANT_70 | 7.0
WIN_SPEED_MANT_80 | 8.0
WIN_SPEED_USE_WAIT | Use wait if available.


I/O Control Codes

Many types of stream interface device drivers use I/O control codes to implement parts of their functionality. I/O control codes are a generic method for extending the functionality of a stream interface driver past that which is defined by the standard stream interface functions. Stream interface drivers can define arbitrary I/O control codes for whatever purposes they require. Microsoft has defined I/O control codes for some particular types of stream interface drivers, such as block device drivers, serial port drivers, and HID class USB devices. If you define additional I/O control codes for your stream interface driver, you are responsible for publishing the information about those codes so that application writers can make full use of your device driver.

These I/O control codes are passed as the dwCode parameter of a stream interface driver’s xxx_IOControl function by an application or by an operating system component. The xxx_IOControl function’s other parameters supply data necessary for each particular I/O control code; the meanings of the other parameters are different for every I/O control code. This section lists all the I/O control codes that Microsoft has defined as well as the meanings of the other parameters to the xxx_IOControl function for each code.


DISK_IOCTL_FORMAT_MEDIA

The FAT file system issues the DISK_IOCTL_FORMAT_MEDIA control code when a device drivers reports that the disk needs a low-level format. Block device drivers indicate this by setting the di_flags parameter of the DISK_INFO structure to the value DISK_INFO_FLAG_UNFORMATTED. The FAT file system will then query the end-user to determine whether or not the device should be formatted before issuing the DISK_IOCTL_FORMAT_MEDIA control code.

Parameters

hDevice
Block device handle.
dwIoControlCode
DISK_IOCTL_FORMAT_MEDIA.
lpInBuffer
Address of a DISK_INFO structure.
nInBufferSize
Size of the DISK_INFO structure.
lpOutBuffer
Not used.
nOutBufferSize
Not used.
lpBytesReturned
Address of a DWORD to receive total bytes returned.
lpOverlapped
Not used.

Remarks

Note that Windows CE version 2.0 and earlier did not issue this request when the driver reported the need to perform a low-level format.


DISK_IOCTL_GETINFO

Block device drivers respond to this I/O control code to return disk information.

Parameters

hDevice
Handle to the block device.
dwIoControlCode
DISK_IOCTL_GETINFO
lpInBuffer
Address of a DISK_INFO structure
nInBufferSize
Set to the size of the DISK_INFO structure
lpOutBuffer
Not used.
nOutBufferSize
Not used.
lpBytesReturned
Address of a DWORD to receive total bytes returned.
lpOverlapped
Not used.

Remarks

On return, the DISK_INFO structure parameters must be filled in with the following information:

di_total_sectors
Total number of blocks on the device
di_bytes_per_sector
Size of a block, in bytes. Values other than 512 are currently not supported.
di_cylinders
If the device supports CHS (cylinder/head/sector) addressing, the driver may report the number of cylinders here. However, the FAT file system does not depend on this information.
di_heads
If the device supports CHS addressing, the driver may report the number of heads per cylinder here. However, the FAT file system does not depend on this information.
di_sectors
If the device supports CHS addressing, the driver may report the number of sectors per track here. However, the FAT file system does not depend on this information.
di_flags
Contains zero or more of the following:
DISK_INFO_FLAG_MBR
The device has or needs a Master Boot Record (MBR).
DISK_INFO_FLAG_CHS_UNCERTAIN
The device does not support CHS addressing; values for di_cylinders/di_heads/di_sectors may be simulated, estimated, or not provided.
DISK_INFO_FLAG_UNFORMATTED
The device requires a low-level format; the FAT file system currently ignores this flag.
DISK_INFO_FLAG_PAGEABLE
The device supports demand paging; read and write requests are synchronous and do not involve any memory manager calls, loader operations, or thread switches.


DISK_IOCTL_GETNAME

Block device drivers respond to this I/O control code to service the FAT file system's request for the name of the folder that the block device should be accessed as by end users. If the driver does not supply a name then the FAT file system will use the default name passed to it by FileSys.exe.

Parameters

hDevice
Handle to the block device.
dwIoControlCode
IOCTL_DISK_GETNAME
lpInBuffer
NULL
nInBufferSize
0
lpOutBuffer
A buffer allocated by the file system driver. The device driver fills this buffer with the folder name. The folder name must be a unicode string.
nOutBufferSize
Set to the size of lpOutBuffer. This is always set to MAX_PATH where MAX_PATH includes the terminating NULL character.
lpBytesReturned
Must be set by the device driver to the length of the returned string plus the terminating NULL character.
lpOverlapped
NULL

Remarks

The block device driver should fill the lpOutBuffer buffer with a unicode string that represents the folder name to use for the block device. The FAT file system will query for a name each time a new block device is mounted. The block device driver can supply the same name for each query or can use different names. The FAT file system will append a number to the folder name if the supplied name is the same as an existing folder name. However, the FAT file system will only make a limited number of different attempts to create a folder for the block device. If the block device driver does not support this I/O control code, then the system's default name is used for all block devices mounted from the block device driver. A block device driver cannot use the name “Storage Card”; that name is reserved. If this name is returned then the request to mount the volume will fail. Windows CE platforms that use languages other than English may have a different reserved folder name for block devices.


DISK_IOCTL_READ

Block device drivers respond to this I/O control code in order to service FAT file system requests to read data from the block device.

Parameters

hDevice
Handle to the block device.
dwIoControlCode
DISK_IOCTL_READ.
lpInBuffer
Address of a SG_REQ structure..
nInBufferSize
Size of a SG_REQ structure.
lpOutBuffer
Not used.
nOutBufferSize
Not used.
lpBytesReturned
Address of a DWORD to receive total bytes returned.
lpOverlapped
Not used.

Return Values

When this function returns, the FAT file system expects the sr_status member of the SG_REQ structure to be set to either ERROR_SUCCESS if the read succeeded, or a standard Win32 error code otherwise. Certain errors are automatically retried, such as ERROR_BAD_UNIT if the device has been removed and ERROR_NOT_READY if the driver is in the process of shutting down or starting up. Block device drivers should return ERROR_GEN_FAILURE for any unknown or unexpected errors.

Remarks

The FAT file system fills in the SG_REQ structure passed to the block device driver as follows:

sr_start
Starting block number.
sr_num_sec
Number of blocks to read.
sr_num_sg
Number of scatter/gather buffers (normally 1).
sr_callback
NULL.
sr_sglist[0].sb_buf
Address of the buffer to read blocks into. Note that this buffer is unaligned.
sr_sglist[0].sb_len
Size of the sr_sglist[0].sb_buf buffer in bytes.

If sr_num_sg is greater than 1, then the block device driver should fill in additional entries in the sr_sglist array.


DISK_IOCTL_SETINFO

Block device drivers respond to this I/O control code to service FAT file system requests to set disk information.

Parameters

hDevice
Block device handle.
dwIoControlCode
DISK_IOCTL_SETINFO.
lpInBuffer
Address of a DISK_INFO structure.
nInBufferSize
Size of the DISK_INFO structure.
lpOutBuffer
Not used.
nOutBufferSize
Not used.
lpBytesReturned
Address of a DWORD to receive total bytes returned.
lpOverlapped
Not used.

Remarks

In addition, the DISK_INFO structure is filled in by the FAT file system in the same way that it expects the block driver to fill the structure for the DISK_IOCTL_GETINFO control code. The purpose of the DISK_IOCTL_SETINFO code is to inform the block driver of discrepancies in the disk information that was provided to the FAT file system, according to information found on the device media itself, such as in the master boot record of a FAT volume. It may not always be possible for a driver to accurately determine the sector size or total number of sectors on a volume, in which case it is up to the file system driver to identify and attempt to correct the discrepancy.


DISK_IOCTL_WRITE

Block device drivers respond to this I/O control code in order to service FAT file system requests to write data to the block device.

Parameters

hDevice
Handle to the block device.
dwIoControlCode
DISK_IOCTL_WRITE.
lpInBuffer
Address of a SG_REQ structure.
nInBufferSize
Size of the SG_REQ structure.
lpOutBuffer
Not used.
nOutBufferSize
Not used.
lpBytesReturned
Address of a DWORD to receive total bytes returned.
lpOverlapped
Not used.

Return Values

When this function returns, the FAT file system expects the sr_status member of the SG_REQ structure to be set to either ERROR_SUCCESS if the write succeeded, or a standard Win32 error code otherwise. Certain errors are automatically retried, such as ERROR_BAD_UNIT if the device has been removed and ERROR_NOT_READY if the driver is in the process of shutting down or starting up. The block device driver should return ERROR_GEN_FAILURE for any unknown or unexpected errors, and ERROR_WRITE_PROTECT for attempts to write to media that is write-protected.

Remarks

The FAT file system fills in the SG_REQ structure passed to the block device driver as follows:

sr_start
Starting block number.
sr_num_sec
Number of blocks to write.
sr_num_sg
Number of scatter/gather buffers (normally 1).
sr_callback
NULL.
sr_sglist[0].sb_buf
Address of the buffer to write blocks into. Note that this buffer is unaligned.
sr_sglist[0].sb_len
Size of the sr_sglist[0].sb_buf buffer in bytes.

Remarks

If sr_num_sg is greater than 1, then the block device driver should fill in additional entries in the sr_sglist array.


IOCTL_HID_ACQUIRE

Unsubscribes an event handle from receiving notifications about HID class device events.

Parameters

hDevice
Handle to the HID class device.
dwIoControlCode
IOCTL_HID_ACQUIRE
lpInBuffer
Pointer to an input buffer containing a SHiddiAcquire structure.
nInBufferSize
The length of the input buffer.
lpOutBuffer
NULL
nOutBufferSize
Not used
lpBytesReturned
A count of the total bytes returned.
lpOverlapped
NULL

Remarks

The input buffer contains a SHiddiAcquire structure which indicates a device ID and whether to acquire or unacquire the device. Since acquiring the device is now performed via the IOCTL_HID_SET_FORMAT control code, the IOCTL_HID_ACQUIRE control code should only be used to unacquire a device. The HID class driver should return an INVALID_PARAMETER error if this code is used to attempt to acquire a device.


IOCTL_HID_ATTACH

Notifies the HID class driver that an application needs to use a device.

Parameters

hDevice
Handle to the HID class device.
dwIoControlCode
IOCTL_HID_ATTACH
lpInBuffer
Pointer to an input buffer containing a SHiddiAttach structure.
nInBufferSize
The length of the input buffer.
lpOutBuffer
Pointer to an output buffer containing a SHiddiAttach structure. Must be equal to lpInBuffer.
nOutBufferSize
Length of the output buffer; must be the same as nInBufferSize.
lpBytesReturned
A count of the total bytes returned.
lpOverlapped
NULL

Remarks

The input and output buffer pointers and lengths must be identical. The buffer must contain a SHiddiAttach structure which is used for both input and output. The device to attach may be specified by ID or by type. If the structure's dwId member is zero, then the device is being specified by type. Otherwise, the dwId member contains the device's ID. If the device is being specified by type, then the actual device attached will be the first one that the HID class driver finds of the correct type. Before returning, the HID class driver must modify the SHiddiAttach structure to reflect the actual ID and type of the attached device.

This I/O control code is also used to detach an attached device, when the bAttaching field of the SHiddiAttach structure is set to FALSE. Devices can only be detached by ID; the dwDevType field is ignored when detaching. After a successful detach, the HID class driver shouldn't modify the SHiddiAttach structure and should return a zero-byte output length.


IOCTL_HID_ENUM_DEVICES

Return a list of devices being managed by HID.

Parameters

hDevice
Handle to the HID class device.
dwIoControlCode
IOCTL_HID_ENUM_DEVICES
lpInBuffer
Pointer to an input buffer containing a ShiddiEnumObjectHeader structure followed by one or more SHiddiEnumObject structures.
nInBufferSize
The length of the input buffer.
lpOutBuffer
Pointer to an output buffer containing a SHiddiEnumObjectHeader structure followed by one or more SHiddiEnumObject structures. Must be equal to lpInBuffer.
nOutBufferSize
Length of the output buffer; must be the same as nInBufferSize.
lpBytesReturned
A count of the total bytes returned.
lpOverlapped
NULL

Remarks

The input and output buffer pointers and lengths must be identical. The buffer must contain a SHiddiEnumDeviceHeader followed by enough space for the HID class driver to write all the SHiddiEnumDevice structures indicated by the header. If the dwId member of the header is 0, the HID class driver should enumerate all available devices of the specified type, or all types, if the dwType member is0. If the dwId member is not 0, the HID class driver should enumerate only the device with that ID, if it exists.


IOCTL_HID_ENUM_OBJECTS

Returns a list of input sources, such as buttons, on a HID class device.

Parameters

hDevice
Handle to the HID class device.
dwIoControlCode
IOCTL_HID_ENUM_OBJECTS
lpInBuffer
Pointer to an input buffer containing a ShiddiEnumObjectHeader structure followed by one or more SHiddiEnumObject structures.
nInBufferSize
The length of the input buffer.
lpOutBuffer
Pointer to an output buffer containing a SHiddiEnumObjectHeader structure followed by one or more SHiddiEnumObject structures. Must be equal to lpInBuffer.
nOutBufferSize
Length of the output buffer; must be the same as nInBufferSize.
lpBytesReturned
A count of the total bytes returned.
lpOverlapped
NULL

Remarks

The input and output buffer pointers and lengths must be identical. The buffer must contain a SHiddiEnumObjectHeader followed by enough space for the HID class driver to write all the SHiddiEnumObject structures indicated by the header. The objects must be listed in a fixed order: axes first, then POVs (for joysticks), then buttons.


IOCTL_HID_GET_INST_DATA

Retrieves device data.

Parameters

hDevice
Handle to the HID class device.
dwIoControlCode
IOCTL_HID_GET_INST_DATA
lpInBuffer
Pointer to a DWORD containing the ID of a previously acquired device.
nInBufferSize
The length of the input buffer.
lpOutBuffer
Pointer to an output buffer in the format specified when the device was acquired.
nOutBufferSize
Length of the output buffer.
lpBytesReturned
A count of the total bytes returned.
lpOverlapped
NULL

Remarks

The input buffer contains a DWORD that is the ID of a previously acquired device. This control code should cause the device data, in the format specified when the device was acquired, to be written into the output buffer. The output buffer length should be set to the number of bytes written, that is, the lesser of the format size or the output buffer size.


IOCTL_HID_POLL

Request the HID class driver to poll a device for status.

Parameters

hDevice
Handle to the HID class device.
dwIoControlCode
IOCTL_HID_POLL
lpInBuffer
NULL
nInBufferSize
Not used
lpOutBuffer
NULL
nOutBufferSize
Not used.
lpBytesReturned
Not used.
lpOverlapped
NULL

Remarks

This I/O control code is not strictly necessary for the Windows CE HID class driver, because USB device status is collected automatically by the USB host controller driver (HCD). This I/O control code is defined in Windows CE only for compatibility with Windows NT. Processing for this code can simply return success without doing any work.


IOCTL_HID_SET_FORMAT

Sets the format of data returned to DI from the device and acquires the device for use.

Parameters

hDevice
Handle to the HID class device.
dwIoControlCode
IOCTL_HID_SET_FORMAT
lpInBuffer
Pointer to an input buffer containing a SHiddiSetFormatHeader structure followed by one or more SHiddiSetFormat structures.
nInBufferSize
The length of the input buffer.
lpOutBuffer
Pointer to an output buffer containing a SHiddiSetFormatHeader structure followed by one or more SHiddiSetFormat structures. Must be equal to lpInBuffer.
nOutBufferSize
Length of the output buffer; must be the same as nInBufferSize.
lpBytesReturned
A count of the total bytes returned.
lpOverlapped
NULL

Remarks

The input buffer will contain as many SHiddiSetFormat structures as given by the SHiddiSetFormatHeader structure's dwCount member. Zero is a legitimate value for this member. The output buffer length should be set to zero on success.


IOCTL_HID_TRANSFER_EVENT

Registers an event handle for the HID class driver to use to be signaled applications when a HID class device generates data.

Parameters

hDevice
Handle to the HID class device.
dwIoControlCode
IOCTL_HID_TRANSFER_EVENT
lpInBuffer
Pointer to an input buffer containing a SHiddiTransferEvent structure.
nInBufferSize
The length of the input buffer.
lpOutBuffer
NULL
nOutBufferSize
Not used.
lpBytesReturned
A count of the total bytes returned.
lpOverlapped
NULL

Remarks

The input buffer contains a SHiddiTransferEvent structure. No output is expected.


IOCTL_SERIAL_CLR_DTR

This code is used by the COM_IOControl function to set the Data Terminal Ready (DTR) signal to low.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

IOCTL_SERIAL_SET_DTR, COM_IOControl, COM_Open


IOCTL_SERIAL_CLR_RTS

This code is used by the COM_IOControl function to set the Request to Send (RTS) signal to low.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

IOCTL_SERIAL_SET_RTS, COM_IOControl, COM_Open


IOCTL_SERIAL_DISABLE_IR

This code sets the device-control block on a specified communications device to disable the infrared port.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

COM_IOControl, COM_Open


IOCTL_SERIAL_ENABLE_IR

This code sets the device-control block on a specified communications device to enable the infrared port.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

COM_IOControl, COM_Open


IOCTL_SERIAL_GET_COMMSTATUS

This code clears any pending communications errors and returns the current communication status.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

COM_IOControl, COM_Open


IOCTL_SERIAL_GET_DCB

This code gets the device-control block from a specified communications device.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

COM_IOControl, COM_Open


IOCTL_SERIAL_GET_MODEMSTATUS

This code retrieves the current modem control-register values.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

COM_IOControl, COM_Open


IOCTL_SERIAL_GET_PROPERTIES

This code retrieves information about the communications properties for a device.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

COM_IOControl, COM_Open


IOCTL_SERIAL_GET_TIMEOUTS

This code gets the time-out parameters for all read and write operations on a specified communications device.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

IOCTL_SERIAL_GET_TIMEOUTS, COM_IOControl, COM_Open


IOCTL_SERIAL_GET_WAIT_MASK

This code retrieves the value of the wait mask.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

IOCTL_SERIAL_SET_WAIT_MASK, COM_IOControl, COM_Open


IOCTL_SERIAL_IMMEDIATE_CHAR

This code transmits a specified character ahead of any pending data in the output buffer of a communications device.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

COM_IOControl, COM_Open


IOCTL_SERIAL_PURGE

This code discards characters from the output or input buffer of a specified communications resource. It can also terminate pending read or write operations on the resource.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

COM_IOControl, COM_Open


IOCTL_SERIAL_SET_BREAK_OFF

This code clears the break state.

Parameters

dwOpenData
Handle returned from call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

COM_IOControl, COM_Open


IOCTL_SERIAL_SET_BREAK_ON

This code sets the break state.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

COM_IOControl, COM_Open


IOCTL_SERIAL_SET_DCB

This code sets the device-control block on a specified communications device.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

COM_IOControl, COM_Open


IOCTL_SERIAL_SET_DTR

This code sets the Data Terminal Ready (DTR) signal to high.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

IOCTL_SERIAL_CLR_DTR, COM_IOControl, COM_Open


IOCTL_SERIAL_SET_QUEUE_SIZE

This code sets the queue sizes of a communications device.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

COM_IOControl, COM_Open


IOCTL_SERIAL_SET_RTS

This code sets the Ready to Send (RTS) signal to high.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

IOCTL_SERIAL_CLR_RTS, COM_IOControl, COM_Open


IOCTL_SERIAL_SET_TIMEOUTS

This code sets the time-out parameters for all read and write operations on a specified communications device.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

IOCTL_SERIAL_GET_TIMEOUTS, COM_IOControl, COM_Open


IOCTL_SERIAL_SET_WAIT_MASK

This code sets the value of the wait mask.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

IOCTL_SERIAL_GET_WAIT_MASK, COM_IOControl, COM_Open


IOCTL_SERIAL_SET_XOFF

This code causes transmission to act as if an XOFF character had been received.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

IOCTL_SERIAL_SET_XON, COM_IOControl, COM_Open


IOCTL_SERIAL_SET_XON

This code causes transmission to act as if an XON character had been received.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Ignored.
dwLenOut
Ignored.
pdwActualOut
Ignored.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

IOCTL_SERIAL_SET_XOFF, COM_IOControl, COM_Open


IOCTL_SERIAL_WAIT_ON_MASK

This code instructs a serial driver to wait for a communications event that matches the event specified in the event mask.

Parameters

dwOpenData
Handle returned from a call to the COM_Open function.
dwCode
Specifies this code.
pBufIn
Ignored.
dwLenIn
Ignored.
pBufOut
Pointer to the DWORD to place in the event mask. The returned mask shows the event that terminated the wait. If a process attempts to change the device handle’s event mask by using the IOCTL_SERIAL_SET_WAIT_MASK call, the driver should return immediately with (DWORD)0 as the returned event mask.
dwLenOut
Specifies the size of the pBufOut pointer.
pdwActualOut
Pointer to a DWORD to return the length of the returned data; should be set to sizeof(DWORD) if there is no error.

Remarks

The control code is declared in the Pegdser.h header file and defined in the Mdd.c file.

See Also

IOCTL_SERIAL_GET_WAIT_MASK, IOCTL_SERIAL_SET_WAIT_MASK, COM_IOControl, COM_Open


Registry Keys for Device Drivers

This section describes the Windows CE–based registry keys related to stream interface drivers. Some registry keys must be supplied by a driver or its installation routine, whereas others are created and maintained by the Device Manager.

Some of the registry keys documented in this section may not be available on some Windows CE–based platforms. For example, a platform with no PC Card sockets does not require an HKEY_LOCAL_MACHINE\Drivers\PCMCIA\ key or any of the subkeys and values typically contained within it.


Drivers\Active

The HKEY_LOCAL_MACHINE\Drivers\Active\ key contains subkeys that the Device Manager uses for tracking active stream interface drivers. These subkeys are all two-digit integers. Do not edit these values directly. The Device Manager creates and maintains these entries for stream interface drivers registered with RegisterDevice.

The subkeys under Active are counters of the drivers loaded by the Device Manager. The following table shows the values for these subkeys.

Subkey
Type
Description
Hnd | REG_DWORD | Specifies the device handle.
Name | REG_SZ | Specifies the device name, such as “PGR1:”.
Key | REG_SZ | Registry path to the device key in \Drivers\PCMCIA.
PnpId | REG_SZ | Specifies a Plug and Play identifier for PC Cards.
Sckt | REG_DWORD | Specifies a PC Card socket and function number in a CARD_SOCKET_HANDLE structure. This is the hSocket parameter passed to the CardRequestIRQ Card Services function.

The following example shows a NewsCard pager that has entries under the Active key.

HKEY_LOCAL_MACHINE
    [Drivers]
        [Active]
            [02]
                SZ: Name = PGR1:
                DWORD: Hnd = 0x32798
                DWORD: Sckt = 0x30000
                SZ: PnpId = Motorola,_Inc.-NewsCard_Data_Receiver-E6DD
                SZ: Key = Drivers\PCMCIA\Motorola,_Inc.-NewsCard_Data_Receiver-E6DD


Drivers\Builtin

The HKEY_LOCAL_MACHINE\Drivers\Builtin key contains subkeys that list which drivers Device Manager loads when the platform is turned on. Each subkey is named after the device driver and contains values described in the following table. Additional values can be stored for purposes specific to the device driver although drivers should never modify keys outside of the driver’s own subkey or keys that the driver did not create itself.

Value name
Value type
Description
Dll | REG_SZ | This required entry specifies the file name for a driver DLL that the Device Manager is to load.
Entry REG_SZ The Entry value, if it exists, names an entry point to the DLL. The Device Manager loads the DLL and calls the specified entry point, with the driver’s registry path as a parameter. When a driver is invoked in this manner, the driver is responsible for calling the RegisterDevice function on its own, and is not tracked by the Device Manager in the Drivers\Active key.

The function named in the Entry value must follow the prototype specified for PFN_DEV_ENTRY: DWORD (*PFN_DEV_ENTRY)(LPTSTR), where the LPSTR parameter is the registry path of the device’s key.
Index | REG_DWORD | This optional value specifies the device index, a value from 0 through 9, that the Device Manager should assign to the driver. If this value is not present, the Device Manager assigns the lowest available index value as the device driver's device file name index.
Keep | REG_SZ | The Keep value works in conjunction with the Entry value; if you have the Keep value, you must also have the Entry value. If the Keep value exists, the Device Manager does not call the FreeLibrary function after the entry point specified in the Entry value returns. This mechanism exists to provide a means to automatically load DLLs at boot time.
Order | REG_DWORD | The Order value specifies the load order for a driver. If two drivers have the same load order value, the drivers load in the order that they occur in the registry. This entry is useful when one driver must load after another. This value is required for non-PC Card devices and is ignored for loading PC Card drivers.
Prefix | REG_SZ | This required value specifies the driver’s device file name prefix. It is a three-character identifier, such as COM.

The following example shows the contents under the Builtin key for the standard serial port driver.

HKEY_LOCAL_MACHINE
    [Drivers]
        [BuiltIn]
            [Serial]
                SZ: Dll = Serial.DLL
                DWORD: Order = 0x00000000 (0)
                SZ: Prefix = COM
                hex: DevConfig = 10 00 00 00 02 00 00 00 10 01 00 00 00 4b 00
                DWORD: DeviceArrayIndex = 0x00000000 (0)
                DWORD: DeviceType = 0x00000000 (0)
                SZ: FriendlyName = Serial Cable on COM1:
                SZ: Tsp = Unimodem.dll


Drivers\Display

The HKEY_LOCAL_MACHINE\Drivers\Display key contains subkeys for display drivers installed on a Windows CE–based platform. Each subkey shares the name of the display driver that it serves. The following table describes the values contained in each subkey.

Value name
Value type
Description
Bpp | REG_SZ | The color depth your display driver uses must be one of the values 1, 2, 4, 5, 6, 8, 15, 16, 24, or 32.
CxScreen | REG_DWORD | The width of the screen, in pixels.
CyScreen | REG_DWORD | The height of the screen, in pixels.
Dll | REG_DWORD | The name of the .dll file that contains the display driver.

The following example shows the contents under the Display key for a sample display driver.

HKEY_LOCAL_MACHINE
    [Drivers]
        [Display]
            [GenericVGA]
                SZ: Dll = GENVGA.DLL
                DWORD: CxScreen = 0x280
                DWORD: CyScreen = 0xF0
                DWORD: Bpp = 8


Drivers\Display\Active

The HKEY_LOCAL_MACHINE\Drivers\Display\Active\ key contains subkeys for display drivers currently in use on a Windows CE–based platform. Each subkey shares the name of the display driver that it serves. The following table describes the values contained in each subkey.

Value name
Value type
Description
BufferMode | DWORD | Controls the correlation between the display adapter’s frame buffer and the frame buffer for any built-in displays on the Windows CE–based platform. BufferMode must be set to one of the following values: 0 means no common frame buffer, 1 means that the top half of the display adapter’s buffer is mirrored on the built-in display, 2 means that a scaled-down version of the display adapter’s frame buffer is mirrored on the built-in display, and 3 means that the built-in display is turned off while this driver is active.
Dll | REG_SZ | Name of the .dll file that contains the display driver.
TapMode | DWORD | Controls how tap or click events are managed. TapMode must be set to one of the following values: 0 (tapping not supported), 1 (tap coordinates are unmodified), 2 (tap coordinates are scaled to match the display driver’s coordinate space), or 3 (tap coordinates are undefined, but tap events are still delivered to applications, optionally with coordinates 0,0).

The following example shows the contents under the Display key for a sample display driver.

HKEY_LOCAL_MACHINE
    [Drivers]
        [Display]
            [Active]
                [GenericVGA]
                    SZ: Dll = GENVGA.DLL
                    DWORD: BufferMode = 0
                    DWORD: TapMode = 0


Drivers\PCMCIA\Detect

The HKEY_LOCAL_MACHINE\Drivers\PCMCIA\Detect\ key contains numbered subkeys that assist the device manager in detecting PC Cards. Each numbered subkey specifies a stream interface driver and a corresponding detection function. The Device Manager calls the detection functions to locate the appropriate driver for an unrecognized PC Card. For example, the Device Manager invokes detection functions when a PC Card lacks a Plug and Play identifier or when a PC Card’s Plug and Play identifier lacks a corresponding subkey under the Drivers\PCMCIA\ key.

The subkeys under Detect are two-digit integers typically assigned by a stream interface driver’s installation routine. The order of the integers determines the order that the Device Manager follows when it calls detection functions. For example, if the Device Manager does not detect a suitable DLL listed in subkey 19, it makes a call to subkey 20. The Device Manager continues this consecutive search process until a function returns a value indicating a successful detection

The following table shows the two values contained within these subkeys.

Value name
Value type
Description
Dll | REG_SZ | Specifies the file name for the DLL that contains the detection function. The Device Manager loads the DLL to call the detection function.
Entry | REG_SZ | Specifies the name of the detection function.

The following example shows an entry for detecting SRAM PC Cards.

HKEY_LOCAL_MACHINE
     [Drivers]
         [PCMCIA]
             [Detect]
                 [20]
                     SZ: Entry = DetectRAMCard
                     SZ: Dll = RAMCARD.dll


Drivers\PCMCIA\Plug-and-Play ID

The Drivers\PCMCIA\ key contains subkeys for known PC Cards. Each subkey is the card’s Plug and Play identifier. The values within a Plug-and-Play ID subkey define the values for a PC Card device with a matching Plug and Play identifier.

The following table shows the required values for this subkey. Additional values can be stored for purposes specific to the device.

Value name
Value type
Description
Dll | REG_SZ | This value specifies the file name for the DLL that contains the stream interface driver. The Device Manager loads the DLL.
Prefix | REG_SZ | This value specifies the device driver’s device file name prefix. It is a three character identifier, such as COM.
Index | REG_DWORD | This optional value specifies the device index (from 0 through 9) that the Device Manager assigns to the driver. If the Index value is not present, the Device Manager assigns the lowest index value available. This index is associated with the device. Only index values from 0 through 9 are allowed.
Context | REG_DWORD | This optional value specifies the device context. If the Context value is present— that is, if it was initialized by the device’s setup application—the Device Manager passes it as the dwInfo parameter to the RegisterDevice function. If it is not present, a pointer to a string containing the registry path to the device’s Drivers\Active\ key is passed as the parameter. The driver’s initialization function then can open this key to read its information. To let the driver read the Drivers\Active key data, do not initialize the Context value.
Ioctl REG_DWORD This optional value specifies an I/O control code that the Device Manager sends to a stream interface driver after loading the driver. If the Ioctl value is present, the Device Manager opens the loaded driver and calls its XXX_IOControl function, passing the I/O control code specified by the Ioctl value. The driver can do any necessary post-initialization in this context. For example, the driver can load modules that use the device.

In addition, the Device Manager broadcasts a WM_DEVICECHANGE message for the new device, and it signals the application notification system by means of the CeEventHasOccurred function, passing it the NOTIFICATION_EVENT_DEVICE_CHANGE message.

The following example shows the registry key for the Motorola NewsCard pager. When the Device Manager matches the pager’s Plug and Play identifier with the registry key, it loads Newscard.dll and registers a device for the NewsCard driver. Because the Index value is specified, the Device Manager registers the pager device as the “PGR1:” device. If no Index value is present, the Device Manager selects an appropriate device index, probably 1 unless another device driver already has registered “PGR1:”. However, when an index is specified, the device driver can support only one PC Card of this type because Device Manager cannot register the card under any device name other than “PGR1:”.

HKEY_LOCAL_MACHINE
    [Drivers]
        [PCMCIA]
            [Motorola,_Inc.-NewsCard_Data_Receiver-E6DD]
                DWORD: Index = 0x1
                SZ: Prefix = PGR
                SZ: Dll = NEWSCARD.DLL


Drivers\PCMCIA\Driver

The name of a generic device driver can be used as a subkey of the Drivers\PCMCIA\ key in conjunction with drivers listed within the Drivers\PCMCIA\Detect\ key. Such Drive r subkeys are similar to the Drivers\PCMCIA\Plug-and-Play-ID key with respect to the values they contain.

The following table shows the values for this subkey. Additional values can be stored for purposes specific to the device.

Value name
Value type
Description
Dll | REG_SZ | This required entry specifies the file name for an driver DLL that the Device Manager is to load.
Prefix | REG_SZ | The Prefix value, if it exists instead of Entry, specifies the device file name prefix of the device driver. It is a three-character identifier, such as COM.
Index | REG_DWORD | Optional. Specifies the device index. The Index value specifies the index assigned to the driver. If the Index value is not present, the Device Manager assigns the lowest index value available. This index will be associated with the device. Only index values from 0 through 9 are allowed. Let the Device Manager determine the index value.
Context | REG_DWORD | Optional. Specifies the device context. If the Context value is present—that is, if it was initialized by the device’s setup application—the Device Manager passes it as the dwInfo parameter to the RegisterDevice function. If it is not present, a pointer to a string containing the registry path to the device’s Active key is passed as the parameter. The driver’s initialization function then can open this key to read its information. To let the driver read the Active key data, do not initialize the Context value.
Ioctl REG_DWORD Optional. Specifies an optional I/O control code that the Device Manager sends to an stream interface driver. If the Ioctl value is present, the Device Manager opens the loaded driver and calls its I/O control function. The Device Manager passes the I/O control code specified by the Iocl registry. The driver does any necessary post-initialization in this context. For example, the driver loads modules that use the device.

In addition, the Device Manager broadcasts a WM_DEVICECHANGE message for the new device and signals the application notification system by means of the PegEventHasOccurred function, passing it the NOTIFICATION_EVENT_DEVICE_CHANGE message.

For example, RAMCard is the name of a driver without a Plug and Play identifier. In addition to being listed within the Drivers\PCMCIA\Detect key, this driver would also have a subkey within Drivers\PCMCIA\ to store values as shown in the following example.

HKEY_LOCAL_MACHINE
     [Drivers]
         [PCMCIA]
             [RAMCard]
                 SZ: Prefix = RAM
                 SZ: Dll = RAMCARD.DLL


Device Driver List

This appendix lists the device drivers that are present in the Platform Builder and what platforms the sample source code supports:

Input Devices
Driver category or name
DLL name
CEPC
D9000
Keyboard+Mouse combo driver | Kbdmouse.dll | X
ODO proprietary keyboard driver | Keybddr.dll | X

Serial Devices
Driver category or name
DLL name
CEPC
D9000
Native serial driver | Serial.dll
16550 serial UART driver | Ser16550.lib | X | X
PC Card serial driver | Ser_card.lib | X | X
Proprietary ODO serial DMA driver | Odo_pdd.lib | X
Dual serial driver | Dualio.dll | X | X

Ethernet Devices
Driver category or name
DLL name
CEPC
D9000
NE2000-compatible Native NDIS driver | Ne2000.dll | X | X
Xircom CE2-compatible NDIS driver | Xircce2.dll | X | X
Proxim RangeLAN2 NDIS driver | Proxim.dll | X | X
NE2000-compatible Ethernet debug driver | Ne2kdbg.lib | X
SMC chipset-compatible Ethernet debug driver | Smc9000.lib | X

Storage Devices
Driver category or name
DLL name
CEPC
D9000
Native PCMCIA bus driver | Pcmcia.dll | X | X
PC Card ATA driver | Atadisk.dll | X | X
PC Card IDE driver | Atadisk.dll | X
PC Card SRAM driver | Sramdisk.dll | X | X
PC Card linear flash driver | Trueffs.dll | X | X
RAMDisk driver | Ramdisk.dll | X | X

Display Devices
Driver category or name
DLL name
CEPC
D9000
ODO
Default Citizen display driver for ODO | Citizen.dll | X
Citizen 2BPP display driver | Cit2bpdr.dll | X
Citizen 4BPP display driver | Cit4bpdr.dll | X
Citizen 8BPP display driver | Cit4bpdr.dll | X
ODO proprietary display driver | Odo2bpp.dll | X
SED 3-3-2 color display driver | Smos332.dll | X
SED 3-3-2 color monochrome driver | Smos4bpp.dll | X
CEPC | X
Generic VGA driver | Ddi_vga8.dll | X
S3 Virge driver | Ddi_s3v.dll | X
S3 Trio 64 driver | Ddi_s364.dll | X
C&T laptop driver | Ddi_ct.dll | X

Touch Screen
Driver category or name
DLL name
CEPC
D9000
Touch (native) Touch.dll X

Modem Devices
Driver category or name
DLL name
CEPC
D9000
Unimodem driver (TAPI service provider) | Unimodem.dll | X | X
TAPI driver | Tapi.dll | X | X
USB devices
USB host interface driver | Usbd.dll | X
USB host controller driver (native) | Ohcd.dll | X
USB mouse client driver | Usbmouse.dll | X

Parallel Devices
Driver category or name
DLL name
CEPC
D9000
Parallel port driver Parallel.dll X X

Printer Devices
Driver category or name
DLL name
CEPC
D9000
Printer driver | Pcl.dll | X | X
Parallel port printer OS component | Prnport.dll | X | X

Audio Devices
Driver category or name
DLL name
CEPC
D9000
Proprietary ODO sound driver | Wavedev.dll | X
SoundBlaster AWE64 PNP ISA driver | Wavedev.dll | X
ACM sample filter driver | Msfilter.dll | X | X
ACM sample PCM driver | Pcmconv.dll | X | X
ACM sample codec driver | Cegsm.dll | X | X

IrDA Devices
Driver category or name
DLL name
CEPC
D9000
Fast IR driver | Nscirda.dll | X
Serial IR driver | Irsir.dll | X | X
Battery driver | Linked to GWES | X
Notification LED driver | Linked to GWES | X


Keyboard Mapping

This appendix provides tables to enable you to map keyboard hardware scan codes to virtual key codes and to map virtual key codes to Unicode characters for several languages.


Virtual-Key Codes

The following table shows the symbolic constant names, hexadecimal values, and keyboard equivalents for the virtual-key codes used by the Windows CE operating system. The codes are listed in numeric order.

Symbolic constant
Value (Hex)
Mouse or keyboard equivalent
VK_LBUTTON | 01 | Left mouse button
VK_RBUTTON | 02 | Right mouse button
VK_CANCEL | 03 | Control-break processing
VK_MBUTTON | 04 | Middle mouse button (three-button mouse)
— 05–07 Undefined
VK_BACK | 08 | BACKSPACE key
VK_TAB | 09 | TAB key
— 0A–0B Undefined
VK_CLEAR | 0C | CLEAR key
VK_RETURN | 0D | ENTER key
— 0E–0F Undefined
VK_SHIFT | 10 | SHIFT key
VK_CONTROL | 11 | CTRL key
VK_MENU | 12 | ALT key
VK_PAUSE | 13 | PAUSE key
VK_CAPITAL | 14 | CAPS LOCK key
— 15–19 Reserved for Kanji systems
— 1A Undefined
VK_ESCAPE | 1B | ESC key
— 1C–1F Reserved for Kanji systems
VK_SPACE | 20 | SPACEBAR
VK_PRIOR | 21 | PAGE UP key
VK_NEXT | 22 | PAGE DOWN key
VK_END | 23 | END key
VK_HOME | 24 | HOME key
VK_LEFT | 25 | LEFT ARROW key
VK_UP | 26 | UP ARROW key
VK_RIGHT | 27 | RIGHT ARROW key
VK_DOWN | 28 | DOWN ARROW key
VK_SELECT | 29 | SELECT key
2A | OEM-specific
VK_EXECUTE | 2B | EXECUTE key
VK_SNAPSHOT | 2C | PRINT SCREEN key for Windows 3.0 and later
VK_INSERT | 2D | INS key
VK_DELETE | 2E | DEL key
VK_HELP | 2F | HELP key
VK_0 | 30 | 0 key
VK_1 | 31 | 1 key
VK_2 | 32 | 2 key
VK_3 | 33 | 3 key
VK_4 | 34 | 4 key
VK_5 | 35 | 5 key
VK_6 | 36 | 6 key
VK_7 | 37 | 7 key
VK_8 | 38 | 8 key
VK_9 | 39 | 9 key
3A–40 | Undefined
VK_A | 41 | A key
VK_B | 42 | B key
VK_C | 43 | C key
VK_D | 44 | D key
VK_E | 45 | E key
VK_F | 46 | F key
VK_G | 47 | G key
VK_H | 48 | H key
VK_I | 49 | I key
VK_J | 4A | J key
VK_K | 4B | K key
VK_L | 4C | L key
VK_M | 4D | M key
VK_N | 4E | N key
VK_O | 4F | O key
VK_P | 50 | P key
VK_Q | 51 | Q key
VK_R | 52 | R key
VK_S | 53 | S key
VK_T | 54 | T key
VK_U | 55 | U key
VK_V | 56 | V key
VK_W | 57 | W key
VK_X | 58 | X key
VK_Y | 59 | Y key
VK_Z | 5A | Z key
VK_LWIN | 5B | Left Windows key (Microsoft Natural Keyboard)
VK_RWIN | 5C | Right Windows key (Microsoft Natural Keyboard)
VK_APPS | 5D | Applications key (Microsoft Natural Keyboard)
5E–5F | Undefined
VK_NUMPAD0 | 60 | Numeric keypad 0 key
VK_NUMPAD1 | 61 | Numeric keypad 1 key
VK_NUMPAD2 | 62 | Numeric keypad 2 key
VK_NUMPAD3 | 63 | Numeric keypad 3 key
VK_NUMPAD4 | 64 | Numeric keypad 4 key
VK_NUMPAD5 | 65 | Numeric keypad 5 key
VK_NUMPAD6 | 66 | Numeric keypad 6 key
VK_NUMPAD7 | 67 | Numeric keypad 7 key
VK_NUMPAD8 | 68 | Numeric keypad 8 key
VK_NUMPAD9 | 69 | Numeric keypad 9 key
VK_MULTIPLY | 6A | Multiply key
VK_ADD | 6B | Add key
VK_SEPARATOR | 6C | Separator key
VK_SUBTRACT | 6D | Subtract key
VK_DECIMAL | 6E | Decimal key
VK_DIVIDE | 6F | Divide key
VK_F1 | 70 | F1 key
VK_F2 | 71 | F2 key
VK_F3 | 72 | F3 key
VK_F4 | 73 | F4 key
VK_F5 | 74 | F5 key
VK_F6 | 75 | F6 key
VK_F7 | 76 | F7 key
VK_F8 | 77 | F8 key
VK_F9 | 78 | F9 key
VK_F10 | 79 | F10 key
VK_F11 | 7A | F11 key
VK_F12 | 7B | F12 key
VK_F13 | 7C | F13 key
VK_F14 | 7D | F14 key
VK_F15 | 7E | F15 key
VK_F16 | 7F | F16 key
VK_F17 | 80H | F17 key
VK_F18 | 81H | F18 key
VK_F19 | 82H | F19 key
VK_F20 | 83H | F20 key
VK_F21 | 84H | F21 key
VK_F22 | 85H | F22 key
VK_F23 | 86H | F23 key
VK_F24 | 87H | F24 key
88–8F | Unassigned
VK_NUMLOCK | 90 | NUM LOCK key
VK_SCROLL | 91 | SCROLL LOCK key
VK_LSHIFT | 0xA0 | Left SHIFT
VK_RSHIFT | 0xA1 | Right SHIFT
VK_LCONTROL | 0xA2 | Left CONTROL
VK_RONTROL | 0xA3 | Right CONTROL
VK_LMENU | 0xA4 | Left ALT
VK_RMENU | 0xA5 | Right ALT
BA-C0 | OEM-specific; reserved. See following tables.
C1-DA | Unassigned
DB-E2 | OEM-specific; reserved. See following tables.
E3 – E4 | OEM-specific
E5 | Unassigned
E6 | OEM-specific
E7-E8 | Unassigned
E9-F5 | OEM-specific
VK_ATTN | F6 | ATTN key
VK_CRSEL | F7 | CRSEL key
VK_EXSEL | F8 | EXSEL key
VK_EREOF | F9 | Erase EOF key
VK_PLAY | FA | PLAY key
VK_ZOOM | FB | ZOOM key
VK_NONAME | FC | Reserved for future use
VK_PA1 | FD | PA1 key
VK_OEM_CLEAR | FE | CLEAR key

OEMs should make special note of the VK key ranges reserved for OEM-specific use: 2A, DB–E4, E6, and E9–F5.

In addition to the VK key assignments in the previous table, Microsoft has assigned the following OEM VK keys.

Symbolic constant
Value (Hex)
Mouse or keyboard equivalent
VK_OEM_SCROLL | 0x91
VK_OEM_1 | 0xBA | “;:” for US
VK_OEM_PLUS | 0xBB | “+” any country
VK_OEM_COMMA | 0xBC | “,” any country
VK_OEM_MINUS | 0xBD | “-” any country
VK_OEM_PERIOD | 0xBE | “.” any country
VK_OEM_2 | 0xBF | “/?” for US
VK_OEM_3 | 0xC0 | “`~” for US
VK_OEM_4 | 0xDB | “[{“ for US
VK_OEM_5 | 0xDC | “\|” for US
VK_OEM_6 | 0xDD | “]}” for US
VK_OEM_7 | 0xDE | “'"“ for US
VK_OEM_8 | 0xDF
VK_OEM_AX | 0xE1 | AX key on Japanese AX keyboard
VK_OEM_102 | 0xE2 | “<>“ or “\|” on RT 102-key keyboard

Finally, for East Asian Input Method Editors (IMEs) the following additional virtual keyboard definitions must be observed.

Symbolic constant
Value (Hex)
Description
VK_DBE_ALPHANUMERIC | 0x0f0 | Changes the mode to alphanumeric
VK_DBE_KATAKANA | 0x0f1 | Changes the mode to Katakana
VK_DBE_HIRAGANA | 0x0f2 | Changes the mode to Hiragana
VK_DBE_SBCSCHAR | 0x0f3 | Changes the mode to single-byte characters
VK_DBE_DBCSCHAR | 0x0f4 | Changes the mode to double-byte characters
VK_DBE_ROMAN | 0x0f5 | Changes the mode to Roman characters
VK_DBE_NOROMAN | 0x0f6 | Changes the mode to non-Roman characters
VK_DBE_ENTERWORDREGISTERMODE | 0x0f7 | Activates the word registration dialog box
VK_DBE_ENTERIMECONFIGMODE | 0x0f8 | Activates a dialog box for setting up an IME environment
VK_DBE_FLUSHSTRING | 0x0f9 | Deletes the undetermined string without determining it
VK_DBE_CODEINPUT | 0x0fa | Changes the mode to code input
VK_DBE_NOCODEINPUT | 0x0fb | Changes the mode to no-code input
VK_DBE_DETERMINESTRING | 0x0fc
VK_DBE_ENTERDLGCONVERSIONMODE | 0x0fd

OEMs should not use the unassigned portions of the VK mapping tables. Microsoft will assign these values in the future. If OEMs require additional VK mappings, they should reuse some of the current OEM and Vender specific assignments.


Vendor-specific Virtual Keys

NEC PC-9800 Series Definitions
VK_OEM_NEC_SEPARATE | 0x6C |
VK_OEM_NEC_EQUAL | 0x92 | “=“ key on numeric pad
VK_OEM_NEC_DP1 | 0xE0 |
VK_OEM_NEC_DP2 | 0xE1 |
VK_OEM_NEC_DP3 | 0xE2 |
VK_OEM_NEC_DP4 | 0xE3 |

Nokia/Ericsson Definitions

Some ICO keyboards generate VK_OEM_F17 and VK_OEM_F18.

VK_OEM_F17 | 0x80
VK_OEM_F18 | 0x81
VK_OEM_F19 | 0x82
VK_OEM_F20 | 0x83
VK_OEM_F21 | 0x84
VK_OEM_F22 | 0x85
VK_OEM_F23 | 0x86
VK_OEM_F24 | 0x87
VK_ERICSSON_BASE | 0xE8
VK_OEM_RESET | (VK_ERICSSON_BASE + 1)
VK_OEM_JUMP | (VK_ERICSSON_BASE + 2)
VK_OEM_PA1 | (VK_ERICSSON_BASE + 3)
VK_OEM_PA2 | (VK_ERICSSON_BASE + 4)
VK_OEM_PA3 | (VK_ERICSSON_BASE + 5)
VK_OEM_WSCTRL | (VK_ERICSSON_BASE + 6)
VK_OEM_CUSEL | (VK_ERICSSON_BASE + 7)
VK_OEM_ATTN | (VK_ERICSSON_BASE + 8)
VK_OEM_FINISH | (VK_ERICSSON_BASE + 9)
VK_OEM_COPY | (VK_ERICSSON_BASE + 10)
VK_OEM_AUTO | (VK_ERICSSON_BASE + 11)
VK_OEM_ENLW | (VK_ERICSSON_BASE + 12)
VK_OEM_BACKTAB | (VK_ERICSSON_BASE + 13)

Fujitsu/OASYS
VK_OEM_FJ_JISHO | 0x92 | // “Dictionary” key
VK_OEM_FJ_MASSHOU | 0x93 | // “Unregister word” key
VK_OEM_FJ_TOUROKU | 0x94 | // “Register word” key
VK_OEM_FJ_LOYA | 0x95 | // “Left OYAYUBI” key
VK_OEM_FJ_ROYA | 0x96 | // “Right OYAYUBI” key
VK_OEM_FJ_000 | 0xB0 | “000” key on numeric pad
VK_OEM_FJ_EQUAL | 0xB1 | “=“ key on numeric pad
VK_OEM_FJ_00 | 0xB3 | “00” key on numeric pad
VK_OEM_OAS_1 | 0xB4 |
VK_OEM_OAS_2 | 0xB5 |
VK_OEM_OAS_3 | 0xB6 |
VK_OEM_OAS_4 | 0xB7 |
VK_OEM_OAS_5 | 0xB8 |
VK_OEM_OAS_6 | 0xB9 |
VK_OEM_OAS_7 | 0xC1 |
VK_OEM_OAS_8 | 0xC2 |
VK_OEM_OAS_9 | 0xC3 |
VK_OEM_OAS_10 | 0xC4 |
VK_OEM_OAS_11 | 0xC5 |
VK_OEM_OAS_12 | 0xC6 |
VK_OEM_OAS_13 | 0xC7 |
VK_OEM_OAS_14 | 0xC8 |
VK_OEM_OAS_15 | 0xC9 |
VK_OEM_OAS_16 | 0xCA |
VK_OEM_OAS_17 | 0xCB |
VK_OEM_OAS_18 | 0xCC |
VK_OEM_OAS_19 | 0xCD |
VK_OEM_OAS_20 | 0xCE |
VK_OEM_OAS_21 | 0xCF |
VK_OEM_OAS_22 | 0xD0 |
VK_OEM_OAS_23 | 0xD1 |
VK_OEM_OAS_24 | 0xD2 |
VK_OEM_OAS_25 | 0xD3 |
VK_OEM_OAS_26 | 0xD4 |
VK_OEM_OAS_27 | 0xD5 |
VK_OEM_OAS_28 | 0xD6 |
VK_OEM_OAS_29 | 0xD7 |
VK_OEM_FJ_DUMMY | 0xEF |

Various Extended or Enhanced Keyboards
VK_ICO_HELP | 0xE3 | Help key on ICO
VK_ICO_00 | 0xE4 | 00 key on ICO
VK_ICO_CLEAR | 0xE6 |


Keyboard Layouts

The keyboard layouts that follow are meant to assist OEMs with their individual keyboard drivers. The information is based on the Windows NT standard keyboard layouts and, therefore, is consistent across products.

The following tables are organized as follows:

  • Column 1: Lists the scan codes.
  • Column 2: Lists the associated Virtual Key.
  • Column 3: Indicates if the resulting character is affected by the CAPLOCK (CAP) key.
  • Column 4: Lists the resulting character. Some characters are represented as hexadecimal numbers.
  • Column 5—N: Describes the expected character when a combination of keys are pressed. Some characters are represented as hexadecimal numbers.

An “@” symbol included as part of the character indicates that the character is a dead key. A dead key, when pressed in combination with second Unicode character, results in a third Unicode character. The dead-key tables following each language-specific keyboard table show the Unicode characters that result from specific dead-key combinations.


Brazilian Keyboard

Scan code
VK_ Key
CAP
Character
SHIFT
CTRL+
ALT
CTRL
SHIFT+
CTRL
29 OEM_3 0 ‘ “
02 1 0 1 ! 00b9
03 2 0 2 @ 00b2 –1 0000
04 3 0 3 # 00b3
05 4 0 4 $ 00a3
06 5 0 5 % 00a2
07 | 6 | 0 | 6 | 00a8@ | 00ac | –1 | 001e
08 7 0 7 &
09 8 0 8 *
0a 9 0 9 (
0b 0 0 0 )
0c OEM_MINUS 0 - _ –1 001f 001f
0d OEM_PLUS 0 = + 00a7
10 Q 1 q Q /
11 W 1 w W ?
12 | E | 1 | e | E | 00b0
13 | R | 1 | r | R
14 | T | 1 | t | T
15 | Y | 1 | y | Y
16 | U | 1 | u | U
17 | I | 1 | i | I
18 | O | 1 | o | O
19 | P | 1 | p | P
1a OEM_4 0 00b4@ `@
1b OEM_6 0 [ { 00aa 001b
2b OEM_5 0 ] } 00ba 001c
1e | A | 1 | a | A
1f | S | 1 | s | S
20 | D | 1 | d | D
21 | F | 1 | f | F
22 | G | 1 | g | G
23 | H | 1 | h | H
24 | J | 1 | j | J
25 | K | 1 | k | K
26 | L | 1 | l | L
27 | OEM_1 | 1 | 00e7 | 00c7 | –1 | 001d
28 OEM_7 0 ~@ ^@
2c | Z | 1 | z | Z
2d | X | 1 | x | X
2e | C | 1 | c | C | 20a2
2f | V | 1 | v | V
30 | B | 1 | b | B
31 | N | 1 | n | N
32 | M | 1 | m | M
33 OEM_COMMA 0 , <
34 OEM_PERIOD 0 . >
35 OEM_2 0 ; :
56 OEM_102 0 \ | –1 001c
53 DECIMAL 0 , ,
73 ABNT_C1 0 / ? 00b0
7e ABNT_C2 0 . .

Dead Key—00b4—Agudo
Unicode character pressed
Unicode character result
0061 | 00e1
0065 | 00e9
0069 | 00ed
006f | 00f3
0075 | 00fa
0079 | 00fd
0041 | 00c1
0045 | 00c9
0049 | 00cd
004f | 00d3
0055 | 00da
0059 | 00dd
0020 | 00b4

Dead Key—0060—Grave
Unicode character pressed
Unicode character result
0061 | 00e0
0065 | 00e8
0069 | 00ec
006f | 00f2
0075 | 00f9
0041 | 00c0
0045 | 00c8
0049 | 00cc
004f | 00d2
0055 | 00d9
0020 | 0060

Dead Key—007e—Til
Unicode character pressed
Unicode character result
0061 | 00e3
006f | 00f5
006e | 00f1
0041 | 00c3
004f | 00d5
004e | 00d1
0020 | 007e

Dead Key—005e—Circunflexo
Unicode character pressed
Unicode character result
0061 | 00e2
0065 | 00ea
0069 | 00ee
006f | 00f4
0075 | 00fb
0041 | 00c2
0045 | 00ca
0049 | 00ce
004f | 00d4
0055 | 00db
0020 | 005e

Dead Key—00a8—Trema
Unicode character pressed
Unicode character result
0061 | 00e4
0065 | 00eb
0069 | 00ef
006f | 00f6
0075 | 00fc
0079 | 00ff
0041 | 00c4
0045 | 00cb
0049 | 00cf
004f | 00d6
0055 | 00dc
0020 | 00a8

Key value
Key name
01 | ESC
0e | BACKSPACE
0f | TAB
1c | ENTER
1d | CTRL
2a | SHIFT
36 | Right SHIFT
37 | NUM *
38 | ALT
39 | SPACE
3a | CAPS LOCK
3b | F1
3c | F2
3d | F3
3e | F4
3f | F5
40 | F6
41 | F7
42 | F8
43 | F9
44 | F10
45 | Pause
46 | SCROLL LOCK
47 | Numeric keypad 7
48 | Numeric keypad 8
49 | Numeric keypad 9
4a | Numeric keypad -
4b | Numeric keypad 4
4c | Numeric keypad 5
4d | Numeric keypad 6
4e | Numeric keypad +
4f | Numeric keypad 1
50 | Numeric keypad 2
51 | Numeric keypad 3
52 | Numeric keypad 0
53 | Numeric keypad DEL
54 | SYS REQ
57 | F11
58 | F12
7c | F13
7d | F14
7e | F15
7f | F16
80 | F17
81 | F18
82 | F19
83 | F20
84 | F21
85 | F22
86 | F23
87 | F24

Key value
Key name extension
1c | Numeric keypad ENTER
1d | Right CONTROL
35 | Numeric keypad /
37 | PRNT SCRN
38 | Right ALT
45 | NUM LOCK
46 | BREAK
47 | HOME
48 | UP
49 | PAGE UP
4b | LEFT
4d | RIGHT
4f | END
50 | DOWN
51 | PAGE DOWN
52 | INSERT
53 | DELETE
54 | <00>
56 | HELP
5b | Left Windows
5c | Right Windows
5d | Application


Dutch Keyboard

Scan code
VK_ Key
CAP
Character
SHIFT
CTRL+
ALT
CTRL
SHIFT+
CTRL
29 OEM_7 0 @ 00a7 00ac
02 1 0 1 ! 00b9
03 2 0 2 " 00b2
04 3 0 3 # 00b3
05 4 0 4 $ 00bc
06 5 0 5 % 00bd
07 6 0 6 & 00be –1 001e
08 7 0 7 _ 00a3
09 8 0 8 ( {
0a 9 0 9 ) }
0b 0 0 0 '
0c OEM_4 0 / ? \ 001c
0d OEM_2 0 00b0 ~@ 00b8@ 001d
10 | Q | 1 | q | Q
11 | W | 1 | w | W
12 | E | 1 | e | E | 20ac
13 | R | 1 | r | R | 00b6
14 | T | 1 | t | T
15 | Y | 1 | y | Y
16 | U | 1 | u | U
17 | I | 1 | i | I
18 | O | 1 | o | O
19 | P | 1 | p | P
1a OEM_6 0 00a8@ ^@
1b OEM_1 0 * |
2b OEM_5 0 < >
1e | A | 1 | a | A
1f | S | 1 | s | S | 00df
20 | D | 1 | d | D
21 | F | 1 | f | F
22 | G | 1 | g | G
23 | H | 1 | h | H
24 | J | 1 | j | J
25 | K | 1 | k | K
26 | L | 1 | l | L
27 OEM_PLUS 0 + 00b1
28 OEM_3 0 00b4@ `@
2c | Z | 1 | z | Z | 00ab
2d | X | 1 | x | X | 00bb
2e | C | 1 | c | C | 00a2
2f | V | 1 | v | V
30 | B | 1 | b | B
31 | N | 1 | n | N
32 | M | 1 | m | M | 00b5
33 OEM_COMMA 0 , ;
34 OEM_PERIOD 0 . : 00b7
35 OEM_MINUS 0 - = –1 001f
56 OEM_102 0 ] [ 00a6 001b
53 DECIMAL 0 , ,

Dead Key—007e—Tilde (~)
Unicode character pressed
Unicode character result
0061 | 00e3
006f | 00f5
006e | 00f1
0041 | 00c3
004f | 00d5
004e | 00d1
0020 | 007e

Dead Key—00b8—Cedille (\x00B8)
Unicode character pressed
Unicode character result
0063 | 00e7
0043 | 00c7
0020 | 00b8

Dead Key—00b4—Accent Aigu (\x00B4)
Unicode character pressed
Unicode character result
0061 | 00e1
0065 | 00e9
0069 | 00ed
006f | 00f3
0075 | 00fa
0079 | 00fd
0041 | 00c1
0045 | 00c9
0049 | 00cd
004f | 00d3
0055 | 00da
0059 | 00dd
0020 | 00b4

Dead Key—0060—Accent Grave (`)
Unicode character pressed
Unicode character result
0061 | 00e0
0065 | 00e8
0069 | 00ec
006f | 00f2
0075 | 00f9
0041 | 00c0
0045 | 00c8
0049 | 00cc
004f | 00d2
0055 | 00d9
0020 | 0060

Dead Key—00a8—Trema (\x00A8)
Unicode character pressed
Unicode character result
0061 | 00e4
0065 | 00eb
0069 | 00ef
006f | 00f6
0075 | 00fc
0079 | 00ff
0041 | 00c4
0045 | 00cb
0049 | 00cf
004f | 00d6
0055 | 00dc
0020 | 00a8

Dead Key—005e—Circumflex (^)
Unicode character pressed
Unicode character result
0061 | 00e2
0065 | 00ea
0069 | 00ee
006f | 00f4
0075 | 00fb
0041 | 00c2
0045 | 00ca
0049 | 00ce
004f | 00d4
0055 | 00db
0020 | 005e

Key value
Key name
01 | ESC
0e | BACKSPACE
0f | TAB
1c | ENTER
1d | CTRL
2a | SHIFT
36 | RECHTS-SHIFT
37 | “NUM-STERRETJE (*)”
38 | ALT
39 | SPATIEBALK
3a | CAPS-LOCK
3b | F1
3c | F2
3d | F3
3e | F4
3f | F5
40 | F6
41 | F7
42 | F8
43 | F9
44 | F10
45 | Pause
46 | SCROLL-LOCK
47 | NUM-7
48 | NUM-8
49 | NUM-9
4a | “NUM-MINTEKEN (-)”
4b | NUM-4
4c | NUM-5
4d | NUM-6
4e | “NUM-PLUSTEKEN (+)”
4f | NUM-1
50 | NUM-2
51 | NUM-3
52 | NUM-0
53 | “NUM-DECIMAAL (,)”
57 | F11
58 | F12

Key value
Key name extension
1c | NUM-ENTER
1d | RECHTS-CTRL
35 | “NUM-SLASH (/)”
37 | PRINT-SCRN
38 | ALT-GR
45 | NUM-LOCK
46 | BREAK
47 | HOME
48 | PIJL-OMHOOG
49 | PGUP
4b | PIJL-LINKS
4d | PIJL-RECHTS
4f | END
50 | PIJL-OMLAAG
51 | PGDN
52 | INS
53 | DEL
54 | <00>
56 | HELP
5b | “Linker Windows”
5c | “Rechter Windows”
5d | Toepassing


French Keyboard

Scan code
VK_ key
CAP
Character
SHIFT
CTRL
CTRL+ALT
SHIFT+CTRL
29 | OEM_7 | 0 | ² | –1
02 1 1 & 1
03 2 1 é 2 –1 ~@
04 3 1 " 3 –1 #
05 4 1 ' 4 –1 {
06 5 1 ( 5 –1 [ 001b
07 6 1 - 6 –1 | 001f
08 7 1 è 7 –1 `@
09 8 1 _ 8 –1 \ 001c
0a 9 1 ç 9 –1 ^ 001e
0b 0 1 à 0 0000 @
0c OEM_4 1 ) ° –1 ]
0d OEM_PLUS 1 = + –1 }
10 | A | 1 | a | A
11 | Z | 1 | z | Z
12 | E | 1 | e | E | –1 | 20ac
13 | R | 1 | r | R
14 | T | 1 | t | T
15 | Y | 1 | y | Y
16 | U | 1 | u | U
17 | I | 1 | i | I
18 | O | 1 | o | O
19 | P | 1 | p | P
1a OEM_6 1 ^@ ¨@ 001b
1b OEM_1 1 $ £ 001d ¤
2b OEM_5 1 * µ 001c
1e | Q | 1 | q | Q
1f | S | 1 | s | S
20 | D | 1 | d | D
21 | F | 1 | f | F
22 | G | 1 | g | G
23 | H | 1 | h | H
24 | J | 1 | j | J
25 | K | 1 | k | K
26 | L | 1 | l | L
27 | M | 1 | m | M
28 OEM_3 1 ù %
2c | W | 1 | w | W
2d | X | 1 | x | X
2e | C | 1 | c | C
2f | V | 1 | v | V
30 | B | 1 | b | B
31 | N | 1 | n | N
32 OEM_COMMA 1 , ?
33 OEM_PERIOD 1 ; .
34 OEM_2 1 : /
35 OEM_8 1 ! §
56 OEM_102 0 < > 001c
53 DECIMAL 0 . .

Dead Key—Accent Circonflexe (^)
Unicode character pressed
Unicode character result
0061 | 00e2
0065 | 00ee
006f | 00f4
0075 | 00fb
0041 | 00c2
0045 | 00ca
0049 | 00ce
004f | 00d4
0055 | 00db
0020 | 005e

Dead Key—00a8—Trema
Unicode character pressed
Unicode character result
0061 | 00e4
0065 | 00eb
0069 | 00ef
006f | 00f6
0075 | 00fc
0079 | 00ff
0041 | 00c4
0045 | 00cb
0049 | 00cf
004f | 00d6
0055 | 00dc
0020 | 00a8

Dead Key 0x007e—Tilde (~)
Unicode character pressed
Unicode character result
0061 | 00e3 | // a -> ã
0041 | 00c3 | // A -> Ã
006e | 00f1 | // n -> ñ
004e | 00d1 | // N -> Ñ
006f | 00f5 | // o -> õ
004f | 00d5 | // O -> Õ
0020 007e // -> ~

Dead Key 0x0060—Accent Grave
Unicode character pressed
Unicode character result
0061 | 00e0 | // a -> à
0065 | 00e8 | // e -> è
0069 | 00ec | // i -> ì
006f | 00f2 | // o -> ò
0075 | 00f9 | // u -> ù
0041 | 00c0 | // A -> À
0045 | 00c8 | // E -> È
0049 | 00cc | // I -> Ì
004f | 00d2 | // O -> Ò
0055 | 00d9 | // U -> Ù
0020 0060 // -> `

Key name
01 | ECHAP
0e | RET.ARR
0f | TAB
1c | ENTREE
1d | CTRL
2a | MAJ
36 | “MAJ DROITE”
37 | “* (PAVE NUM.)”
38 | ALT
39 | ESPACE
3a | VERR.MAJ
3b | F1
3c | F2
3d | F3
3e | F4
3f | F5
40 | F6
41 | F7
42 | F8
43 | F9
44 | F10
45 | Pause
46 | DEFIL
47 | “7 (PAVE NUM.)”
48 | “8 (PAVE NUM.)”
49 | “9 (PAVE NUM.)”
4a | “- (PAVE NUM.)”
4b | “4 (PAVE NUM.)”
4c | “5 (PAVE NUM.)”
4d | “6 (PAVE NUM.)”
4e | “+ (PAVE NUM.)”
4f | “1 (PAVE NUM.)”
50 | “2 (PAVE NUM.)”
51 | “3 (PAVE NUM.)”
52 | “0 (PAVE NUM.)”
53 | “. (PAVE NUM.)”
57 | F11
58 | F12

Key-name extension
1c | “ENTREE (PAVE NUM.)”
1d | “CTRL DROITE”
35 | “/ (PAVE NUM.)”
37 | Impr.Ecran
38 | “ALT DROITE”
45 | Ver.Num
46 | ATTN
47 | ORIGINE
48 | HAUT
49 | PG.PREC
4b | GAUCHE
4d | DROITE
4f | FIN
50 | BAS
51 | PG.SUIV
52 | INS
53 | SUPPR
54 | <00>
56 | AIDE
5b | “WINDOWS GAUCHE”
5c | “WINDOWS DROITE”
5d | APPLICATION


German Keyboard

Scan code
VK_ Key
CAP
Character
SHIFT
CTRL+
ALT
CTRL
SHIFT+
CTRL
29 OEM_5 0 ^@ 00b0
02 1 1 1 !
03 2 1 2 " 00b2 –1 0000
04 | 3 | 1 | 3 | 00a7 | 00b3
05 4 1 4 $
06 5 1 5 %
07 6 1 6 & –1 –1 001e
08 7 1 7 / {
09 8 1 8 ( [
0a 9 1 9 ) ]
0b 0 1 0 = }
0c OEM_4 1 00df ? \
0d OEM_6 0 00b4@ `@
10 Q 1 q Q @
11 | W | 1 | w | W
12 | E | 1 | e | E | 20ac
13 | R | 1 | r | R
14 | T | 1 | t | T
15 | Z | 1 | z | Z
16 | U | 1 | u | U
17 | I | 1 | i | I
18 | O | 1 | o | O
19 | P | 1 | p | P
1a | OEM_1 | 1 | 00fc | 00dc | –1 | 001b
1b OEM_PLUS 1 + * ~ 001d
2b OEM_2 1 # ' –1 001c
1e | A | 1 | a | A
1f | S | 1 | s | S
20 | D | 1 | d | D
21 | F | 1 | f | F
22 | G | 1 | g | G
23 | H | 1 | h | H
24 | J | 1 | j | J
25 | K | 1 | k | K
26 | L | 1 | l | L
27 | OEM_3 | 1 | 00f6 | 00d6
28 | OEM_7 | 1 | 00e4 | 00c4
2c | Y | 1 | y | Y
2d | X | 1 | x | X
2e | C | 1 | c | C
2f | V | 1 | v | V
30 | B | 1 | b | B
31 | N | 1 | n | N
32 | M | 1 | m | M | 00b5
33 OEM_COMMA 1 , ;
34 OEM_PERIOD 1 . :
35 OEM_MINUS 0 - _ –1 –1 001f
56 OEM_102 0 < > |
53 DECIMAL 0 , ,

Dead Key—005e—Zirkumflex
Unicode character pressed
Unicode character result
0061 | 00e2
0065 | 00ea
0069 | 00ee
006f | 00f4
0075 | 00fb
0041 | 00c2
0045 | 00ca
0049 | 00ce
004f | 00d4
0055 | 00db
0020 | 005e

Dead Key—00b4—Akut
Unicode character pressed
Unicode character result
0061 | 00e1
0065 | 00e9
0069 | 00ed
006f | 00f3
0075 | 00fa
0079 | 00fd
0041 | 00c1
0045 | 00c9
0049 | 00cd
004f | 00d3
0055 | 00da
0059 | 00dd
0020 | 00b4

Dead Key—0060—Gravis
Unicode character pressed
Unicode character result
0061 | 00e0
0065 | 00e8
0069 | 00ec
006f | 00f2
0075 | 00f9
0041 | 00c0
0045 | 00c8
0049 | 00cc
004f | 00d2
0055 | 00d9
0020 | 0060

Key value
Key name
01 | ESC
0e | R\x00DCCK
0f | TABULATOR
1c | EINGABE
1d | STRG
2a | UMSCHALT
36 | “UMSCHALT RECHTS”
37 | “ (ZEHNERTASTATUR)”
38 | ALT
39 | LEER
3a | FESTSTELL
3b | F1
3c | F2
3d | F3
3e | F4
3f | F5
40 | F6
41 | F7
42 | F8
43 | F9
44 | F10
45 | PAUSE
46 | ROLLEN-FESTSTELL
47 | “7 (ZEHNERTASTATUR)”
48 | “8 (ZEHNERTASTATUR)”
49 | “9 (ZEHNERTASTATUR)”
4a | “- (ZEHNERTASTATUR)”
4b | “4 (ZEHNERTASTATUR)”
4c | “5 (ZEHNERTASTATUR)”
4d | “6 (ZEHNERTASTATUR)”
4e | “+ (ZEHNERTASTATUR)”
4f | “1 (ZEHNERTASTATUR)”
50 | “2 (ZEHNERTASTATUR)”
51 | “3 (ZEHNERTASTATUR)”
52 | “0 (ZEHNERTASTATUR)”
53 | “KOMMA (ZEHNERTASTATUR)”
57 | F11
58 | F12

Key value
Key-name extension
1c | “EINGABE (ZEHNERTASTATUR)”
1d | STRG-RECHTS
35 | “ (ZEHNERTASTATUR)”
37 | DRUCK
38 | “ALT GR”
45 | NUM-FESTSTELL
46 | UNTBR
47 | POS1
48 | NACH-OBEN
49 | BILD-NACH-OBEN
4b | NACH-LINKS
4d | NACH-RECHTS
4f | ENDE
50 | NACH-UNTEN
51 | BILD-NACH-UNTEN
52 | EINFG
53 | ENTF
54 | <00>
56 | HILFE
5b | “LINKE WINDOWS”
5c | “RECHTE WINDOWS”
5d | ANWENDUNG


Italian Keyboard

Scan code
VK_ Key
CAP
Character
SHIFT
CTRL
CTRL+ALT
SHIFT+
CTRL+
ALT
SHIFT+
CTRL
29 OEM_5 0 \ |
02 1 0 1 !
03 2 0 2 "
04 | 3 | 0 | 3 | 00a3 | –1
05 4 0 4 $
06 5 0 5 % –1 20ac
07 6 0 6 & –1 –1 –1 001e
08 7 0 7 / –1
09 8 0 8 ( –1
0a 9 0 9 ) –1
0b 0 0 0 = –1
0c OEM_4 0 ' ?
0d OEM_6 0 00ec ^
10 | Q | 1 | q | Q | –1
11 | W | 1 | w | W
12 | E | 1 | e | E | –1 | 20ac
13 | R | 1 | r | R
14 | T | 1 | t | T
15 | Y | 1 | y | Y
16 | U | 1 | u | U
17 | I | 1 | i | I
18 | O | 1 | o | O
19 | P | 1 | p | P
1a OEM_1 0 00e8 00e9 001b [ {
1b OEM_PLUS 0 + * 001d ] }
2b | OEM_2 | 0 | 00f9 | 00a7 | 001c
1e | A | 1 | a | A
1f | S | 1 | s | S
20 | D | 1 | d | D
21 | F | 1 | f | F
22 | G | 1 | g | G
23 | H | 1 | h | H
24 | J | 1 | j | J
25 | K | 1 | k | K
26 | L | 1 | l | L
27 OEM_3 0 00f2 00e7 –1 @ –1
28 OEM_7 0 00e0 00b0 –1 # –1
2c | Z | 1 | z | Z
2d | X | 1 | x | X
2e | C | 1 | c | C
2f | V | 1 | v | V
30 | B | 1 | b | B
31 | N | 1 | n | N
32 | M | 1 | m | M
33 OEM_COMMA 0 , ;
34 OEM_PERIOD 0 . :
35 OEM_MINUS 0 - _ 001f
56 OEM_102 0 < > 001c
53 DECIMAL 0 . . –1

Key value
Key name
01 | ESC
0e | BACKSPACE
0f | TAB
1c | INVIO
1d | CTRL
2a | MAIUSC
36 | “MAIUSC (DESTRA)”
37 | “* (Tn)”
38 | ALT
39 | “BARRA SPAZIATRICE”
3a | “BLOC MAIUS”
3b | F1
3c | F2
3d | F3
3e | F4
3f | F5
40 | F6
41 | F7
42 | F8
43 | F9
44 | F10
45 | PAUSA
46 | “BLOC SCORR”
47 | “7 (Tn)”
48 | “8 (Tn)”
49 | “9 (Tn)”
4a | “- (Tn)”
4b | “4 (Tn)”
4c | “5 (Tn)”
4d | “6 (Tn)”
4e | “PI\x00D9 (Tn)”
4f | “1 (Tn)”
50 | “2 (Tn)”
51 | “3 (Tn)”
52 | “0 (Tn)”
53 | “. (Tn)”
57 | F11
58 | F12

Key value
Key-name extension
1c | “INVIO (TN)”
1d | “CTRL (DESTRA)”
35 | “/ (Tn)”
37 | STAMPA
38 | “ALT GR”
45 | “BLOC NUM”
46 | INTERR
47 | HOME
48 | “Freccia SU”
49 | PGSU
4b | “Freccia SINISTRA”
4d | “Freccia DESTRA”
4f | FINE
50 | “Freccia GI\x00D9”
51 | PGGI\x00D9
52 | INS
54 | <00>
56 | AIUTO
53 | CANCELLA
5b | “WINDOWS SINISTRO”
5c | “WINDOWS DESTRO”
5d | APPLICAZIONE


Japanese Keyboard

The Japanese keyboard definition is more complex than other keyboards because of the language complexities. What follows is the information required to create a Japanese 106 keyboard layout. An example of a Japanese 106 keyboard can be found in the \CEPC platform directory.

The following table shows the Scan Key to VK (virtual key) mapping.

Scan code
VK_ key
00 | _none_
01 | ESCAPE
02 | 1
03 | 2
04 | 3
05 | 4
06 | 5
07 | 6
08 | 7
09 | 8
0A | 9
0B | 0
0C | OEM_MINUS
0D | OEM_7
0E | BACK
0F | TAB
10 | Q
11 | W
12 | E
13 | R
14 | T
15 | Y
16 | U
17 | I
18 | O
19 | P
1A | OEM_3
1B | OEM_4
1C | RETURN
1D | LCONTROL
1E | A
1F | S
20 | D
21 | F
22 | G
23 | H
24 | J
25 | K
26 | L
27 | OEM_PLUS
28 | OEM_1
29 | DBE_SBCSCHAR
2A | LSHIFT
2B | OEM_6
2C | Z
2D | X
2E | C
2F | V
30 | B
31 | N
32 | M
33 | OEM_COMMA
34 | OEM_PERIOD
35 | OEM_2
36 | RSHIFT
37 | MULTIPLY
38 | LMENU
39 “ “
3A | DBE_ALPHANUMERIC
3B | F1
3C | F2
3D | F3
3E | F4
3F | F5
40 | F6
41 | F7
42 | F8
43 | F9
44 | F10
45 | NUMLOCK
46 | OEM_SCROLL
47 | HOME
48 | UP
49 | PRIOR
4A | SUBTRACT
4B | LEFT
4C | CLEAR
4D | RIGHT
4E | ADD
4F | END
50 | DOWN
51 | NEXT
52 | INSERT
53 | DELETE
54 | SNAPSHOT
55 | _none_
56 | _none_
57 | F11
58 | F12
59 | CLEAR
5A | NONAME
5B | NONAME
5C | NONAME
5D | EREOF
5E | _none_
5F | NONAME
60 | _none_
61 | _none_
62 | _none_
63 | _none_
64 | F13
65 | F14
66 | F15
67 | F16
68 | F17
69 | F18
6A | F19
6B | F20
6C | F21
6D | F22
6E | F23
6F | _none_
70 | DBE_HIRAGANA
71 | _none_
72 | _none_
73 | OEM_102
74 | _none_
75 | _none_
76 | F24
77 | _none_
78 | _none_
79 | CONVERT
7A | _none_
7B | NONCONVERT
7C | TAB
7D | OEM_5
7E | ABNT_C2
7F | OEM_PA2
E01C | RETURN
E01D | RCONTROL
E033 | _none_
E035 | DIVIDE
E037 | SNAPSHOT
E038 | RMENU
E042 | _none_
E043 | _none_
E044 | _none_
E046 | CANCEL
E047 | HOME
E048 | UP
E049 | PRIOR
E04B | LEFT
E04D | RIGHT
E04F | END
E050 | DOWN
E051 | NEXT
E052 | INSERT
E053 | DELETE
E05B | LWIN
E05C | RWIN
E05D | APPS
E05E | POWER
E05F | SLEEP
E0F1 | _none_
E0F2 | _none_
E11D | PAUSE (See Below)

The BREAK key is sent as the sequence E1, left CTRL, NUMLOCK. The keyboard driver must convert the E1+left CTRL sequence to the BREAK key and ignore the NUMLOCK.

The next part of the Japanese keyboard is the VK to character mapping. This mapping is dependent upon the state of other modifier keys. Some characters are shown as symbol names, which are described after these tables. The processing of VK keys should be performed in the order in which the following tables are laid out. The following table shows the characters that should be generated for each virtual key, both alone and in combination with modifier keys.

Virtual key
CAPLOCK / KANALOCK
Character
SHIFT
KANA
KANA+SHIFT
0 | KANALOK | 0 | WCH_NONE | WCH_WA | WCH_WO
1 KANALOK 1 ! WCH_NU WCH_NU
3 KANALOK 3 # WCH_A WCH_AA
4 KANALOK 4 $ WCH_U WCH_UU
5 KANALOK 5 % WCH_E WCH_EE
7 | KANALOK | 7 | 0x27 | WCH_YA | WCH_YAA
8 KANALOK 8 ( WCH_YU WCH_YUU
9 KANALOK 9 ) WCH_YO WCH_YOO
A | CAPLOK| KANALOK | a | A | WCH_TI | WCH_TI
B | CAPLOK | KANALOK | b | B | WCH_KO | WCH_KO
C | CAPLOK | KANALOK | c | C | WCH_SO | WCH_SO
D | CAPLOK | KANALOK | d | D | WCH_SI | WCH_SI
E | CAPLOK | KANALOK | e | E | WCH_I | WCH_II
F | CAPLOK | KANALOK | f' | F | WCH_HA | WCH_HA
G | CAPLOK | KANALOK | g | G | WCH_KI | WCH_KI
H | CAPLOK | KANALOK | h | H | WCH_KU | WCH_KU
I | CAPLOK | KANALOK | i | I | WCH_NI | WCH_NI
J | CAPLOK | KANALOK | j | J | WCH_MA | WCH_MA
K | CAPLOK | KANALOK | k | K | WCH_NO | WCH_NO
L | CAPLOK | KANALOK | l | L | WCH_RI | WCH_RI
M | CAPLOK | KANALOK | m | M | WCH_MO | WCH_MO
N | CAPLOK | KANALOK | n | N | WCH_MI | WCH_MI
O | CAPLOK | KANALOK | o | O | WCH_RA | WCH_RA
P | CAPLOK | KANALOK | p | P | WCH_SE | WCH_SE
Q | CAPLOK | KANALOK | q | Q | WCH_TA | WCH_TA
R | CAPLOK | KANALOK | r | R | WCH_SU | WCH_SU
S | CAPLOK | KANALOK | s | S | WCH_TO | WCH_TO
T | CAPLOK | KANALOK | t | T | WCH_KA | WCH_KA
U | CAPLOK | KANALOK | u | U | WCH_NA | WCH_NA
V | CAPLOK | KANALOK | v | V | WCH_HI | WCH_HI
W | CAPLOK | KANALOK | w | W | WCH_TE | WCH_TE
X | CAPLOK | KANALOK | x | X | WCH_SA | WCH_SA
Y | CAPLOK | KANALOK | y | Y | WCH_NN | WCH_NN
Z | CAPLOK | KANALOK | z | Z | WCH_TU | WCH_TUU
OEM_1 KANALOK “:” * WCH_KE WCH_KE
OEM_2 KANALOK / ? WCH_ME WCH_MD
OEM_3 KANALOK @ “`” WCH_VS WCH_VS
OEM_7 KANALOK ^ ~ WCH_HE WCH_HE
OEM_8 | 0 | WCH_NONE | WCH_NONE | WCH_NONE | WCH_NONE
OEM_COMMA KANALOK “,” < WCH_NE WCH_IC
OEM_PERIOD KANALOK “.” > WCH_RU WCH_IP
OEM_PLUS KANALOK “;” + WCH_RE WCH_RE
TAB | 0 | \t | \t | \t | \t
ADD 0 + + + +
DECIMAL 0 “.” “.” “.” “.”
DIVIDE 0 / / / /
MULTIPLY 0 * * * *
SUBTRACT 0 - - - -

Note CAPSLOK and KANALOK indicate that a key is affected by the state of the CAPS LOCK and KANA LOCK keys.

Virtual key
CAPSLOCK / KANALOCK
Char
SHIFT
KANA
KANA+SHIFT
BACK | 0 | \b | \b | \b | \b
CANCEL | 0 | 0x03 | 0x03 | 0x03 | 0x03
ESCAPE | 0 | 0x1b | 0x1b | 0x1b | 0x1b
OEM_4 KANALOK [ { WCH_SVS WCH_OB
OEM_5 KANALOK \\ | WCH_PS WCH_PS
OEM_102 KANALOK \\ _ WCH_RO WCH_RO
OEM_6 KANALOK ] } WCH_MU WCH_CB
RETURN | 0 | \r | \r | \r | \r
SPACE 0 “ “ “ “ “ “ “ “

VK_key
CTRL
KANA+CTRL
BACK | 0x7f | 0x7f
CANCEL | 0x03 | 0x03
ESCAPE | 0x1b | 0x1b
OEM_4 | 0x1b | 0x1b
OEM_5 | 0x1c | 0x1c
OEM_102 | 0x1c | 0x1c
OEM_6 | 0x1d | 0x1d
RETURN | \n | \n
SPACE | 0x20 | 0x20

Virtual key
CAPSLOCK / KANALOK*
Char
SHIFT
KANA
KANA+
SHIFT
2 KANALOK 2 " WCH_HU WCH_HU
6 KANALOK 6 & WCH_O WCH_OO
OEM_MINUS KANALOK - = WCH_HO WCH_HO

Virtual key
CTRL
KANA+CTRL
SHIFT+CTRL
KANA+
SHIFT+
CTRL
2 | WCH_NONE | WCH_NONE | 0x00 | 0x00
6 | WCH_NONE | WCH_NONE | 0x1e | 0x1e
OEM_MINUS | WCH_NONE | WCH_NONE | 0x1f | 0x1f

VK_
CAPLOK / KANALOK
Char
SHIFT
KANA
KANA+SHIFT
NUMPAD0 | 0 | 0 | WCH_NONE | 0 | WCH_NONE
NUMPAD1 | 0 | 1 | WCH_NONE | 1 | WCH_NONE
NUMPAD2 | 0 | 2 | WCH_NONE | 2 | WCH_NONE
NUMPAD3 | 0 | 3 | WCH_NONE | 3 | WCH_NONE
NUMPAD4 | 0 | 4 | WCH_NONE | 4 | WCH_NONE
NUMPAD5 | 0 | 5 | WCH_NONE | 5 | WCH_NONE
NUMPAD6 | 0 | 6 | WCH_NONE | 6 | WCH_NONE
NUMPAD7 | 0 | 7 | WCH_NONE | 7 | WCH_NONE
NUMPAD8 | 0 | 8 | WCH_NONE | 8 | WCH_NONE
NUMPAD9 | 0 | 9 | WCH_NONE | 9 | WCH_NONE

The following table defines the character symbols used in the previous table.

Define
Unicode value
Character
WCH_IP | FF61 | Ideographic period
WCH_OB | FF62 | Opening corner bracket
WCH_CB | FF63 | Closing corner bracket
WCH_IC | FF64 | Ideographic comma
WCH_MD | FF65 | Katakana middle dot
WCH_WO | FF66 | Katakana syllable wo
WCH_AA | FF67 | Katakana letter lowercase a
WCH_II | FF68 | Katakana letter lowercase i
WCH_UU | FF69 | Katakana letter lowercase u
WCH_EE | FF6A | Katakana letter lowercase e
WCH_OO | FF6B | Katakana letter lowercase o
WCH_YAA | FF6C | Katakana syllable lowercase ya
WCH_YUU | FF6D | Katakana syllable lowercase yu
WCH_YOO | FF6E | Katakana syllable lowercase yo
WCH_TUU | FF6F | Katakana syllable lowercase tu
WCH_PS | FF70 | Katakana prolonged sound mark
WCH_A | FF71 | Katakana letter A
WCH_I | FF72 | Katakana letter I
WCH_U | FF73 | Katakana letter U
WCH_E | FF74 | Katakana letter E
WCH_O | FF75 | Katakana letter O
WCH_KA | FF76 | Katakana syllable ka
WCH_KI | FF77 | Katakana syllable ki
WCH_KU | FF78 | Katakana syllable ku
WCH_KE | FF79 | Katakana syllable ke
WCH_KO | FF7A | Katakana syllable ko
WCH_SA | FF7B | Katakana syllable sa
WCH_SI | FF7C | Katakana syllable si
WCH_SU | FF7D | Katakana syllable su
WCH_SE | FF7E | Katakana syllable su
WCH_SO | FF7F | Katakana syllable so
WCH_TA | FF80 | Katakana syllable ta
WCH_TI | FF81 | Katakana syllable ti
WCH_TU | FF82 | Katakana syllable tu
WCH_TE | FF83 | Katakana syllable te
WCH_TO | FF84 | Katakana syllable to
WCH_NA | FF85 | Katakana syllable na
WCH_NI | FF86 | Katakana syllable ni
WCH_NU | FF87 | Katakana syllable nu
WCH_NE | FF88 | Katakana syllable ne
WCH_NO | FF89 | Katakana syllable no
WCH_HA | FF8A | Katakana syllable ha
WCH_HI | FF8B | Katakana syllable hi
WCH_HU | FF8C | Katakana syllable hu
WCH_HE | FF8D | Katakana syllable he
WCH_HO | FF8E | Katakana syllable ho
WCH_MA | FF8F | Katakana syllable ma
WCH_MI | FF90 | Katakana syllable mi
WCH_MU | FF91 | Katakana syllable mu
WCH_ME | FF92 | Katakana syllable me
WCH_MO | FF93 | Katakana syllable mo
WCH_YA | FF94 | Katakana syllable ya
WCH_YU | FF95 | Katakana syllable yu
WCH_YO | FF96 | Katakana syllable yo
WCH_RA | FF97 | Katakana syllable ra
WCH_RI | FF98 | Katakana syllable ri
WCH_RU | FF99 | Katakana syllable ru
WCH_RE | FF9A | Katakana syllable re
WCH_RO | FF9B | Katakana syllable ro
WCH_WA | FF9C | Katakana syllable wa
WCH_NN | FF9D | Katakana letter n
WCH_VS | FF9E | Katakana voiced sound mark
WCH_SVS | FF9F | Katakana semi-voiced sound mark


Portuguese Keyboard

Scan code
VK_ key
CAP
Character
SHIFT
CTRL+
ALT
CTRL
SHIFT+
CTRL
29 OEM_5 0 \ |
02 1 0 1 !
03 2 0 2 " @
04 3 0 3 # 00a3
05 4 0 4 $ 00a7
06 5 0 5 % 20ac
07 6 0 6 & –1 –1 001e
08 7 0 7 / {
09 8 0 8 ( [
0a 9 0 9 ) ]
0b 0 0 0 = }
0c OEM_4 0 ' ?
0d | OEM_6 | 0 | 00ab | 00bb
10 | Q | 1 | q | Q
11 | W | 1 | w | W
12 | E | 1 | e | E | 20ac
13 | R | 1 | r | R
14 | T | 1 | t | T
15 | Y | 1 | y | Y
16 | U | 1 | u | U
17 | I | 1 | i | I
18 | O | 1 | o | O
19 | P | 1 | p | P
1a OEM_PLUS 0 + * 00a8@
1b OEM_1 0 00b4@ `@ ]
2b OEM_2 0 ~@ ^@
1e | A | 1 | a | A
1f | S | 1 | s | S
20 | D | 1 | d | D
21 | F | 1 | f | F
22 | G | 1 | g | G
23 | H | 1 | h | H
24 | J | 1 | j | J
25 | K | 1 | k | K
26 | L | 1 | l | L
27 | OEM_3 | 1 | 00e7 | 00c7
28 | OEM_7 | 0 | 00ba | 00aa
2c | Z | 1 | z | Z
2d | X | 1 | x | X
2e | C | 1 | c | C
2f | V | 1 | v | V
30 | B | 1 | b | B
31 | N | 1 | n | N
32 | M | 1 | m | M
33 OEM_COMMA 0 , ;
34 OEM_PERIOD 0 . :
35 OEM_MINUS 0 - _ –1 001f
56 OEM_102 0 < >
53 DECIMAL 0 . .

Dead Key—00b4—Agudo
Unicode character pressed
Unicode character result
0061 | 00e1
0065 | 00e9
0069 | 00ed
006f | 00f3
0075 | 00fa
0079 | 00fd
0041 | 00c1
0045 | 00c9
0049 | 00cd
004f | 00d3
0055 | 00da
0059 | 00dd
0020 | 00b4

Dead Key—0060—Grave
Unicode character pressed
Unicode character result
0061 | 00e0
0065 | 00e8
0069 | 00ec
006f | 00f2
0075 | 00f9
0041 | 00c0
0045 | 00c8
0049 | 00cc
004f | 00d2
0055 | 00d9
0020 | 0060

Dead Key—00a8—Trema
Unicode character pressed
Unicode character result
0061 | 00e4
0065 | 00eb
0069 | 00ef
006f | 00f6
0075 | 00fc
0079 | 00ff
0041 | 00c4
0045 | 00cb
0049 | 00cf
004f | 00d6
0055 | 00dc
0020 | 00a8

Dead Key—007e—Til
Unicode character pressed
Unicode character result
0061 | 00e3
006f | 00f5
006e | 00f1
0041 | 00c3
004f | 00d5
004e | 00d1
0020 | 007e

Dead Key—005e—Circunflexo
Unicode character pressed
Unicode character result
0061 | 00e2
0065 | 00ea
0069 | 00ee
006f | 00f4
0075 | 00fb
0041 | 00c2
0045 | 00ca
0049 | 00ce
004f | 00d4
0055 | 00db
0020 | 005e

Key value
Key name
01 | ESC
0e | BACKSPACE
0f | TAB
1c | ENTER
1d | CTRL
2a | SHIFT
36 | SHIFT DIREITO
37 | ASTERISCO (TN)
38 | ALT
39 | BARRA DE ESPA\x00C7OS
3a | CAPSLOCK
3b | F1
3c | F2
3d | F3
3e | F4
3f | F5
40 | F6
41 | F7
42 | F8
43 | F9
44 | F10
45 | PAUSE
46 | SCROLL LOCK
47 | 7 (TN)
48 | 8 (TN)
49 | 9 (TN)
4a | MENOS (TN)
4b | 4 (TN)
4c | 5 (TN)
4d | 6 (TN)
4e | MAIS (TN)
4f | 1 (TN)
50 | 2 (TN)
51 | 3 (TN)
52 | 0 (TN)
53 | PONTO DECIMAL (TN)
57 | F11
58 | F12

Key value
Key-name extension
1c | ENTER (TN)
1d | CTRL DIREITO
35 | BARRA (TN)
37 | PRINT SCRN
38 | ALT DIREITO
45 | NUM LOCK
46 | BREAK
47 | HOME
48 | SETA ACIMA
49 | PGUP
4b | SETA \x00C0 ESQUERDA
4d | SETA \x00C0 DIREITA
4f | END
50 | SETA ABAIXO
51 | PGDOWN
52 | INSERT
53 | DELETE
54 | <00>
56 | HELP
5b | WINDOWS ESQUERDA
5c | WINDOWS DIREITA
5d | APLICATIVO


Spanish Keyboard

Scan code
VK_ key
CAP
Character
SHIFT
CTRL
CTRL+
ALT
SHIFT+
CTRL
29 OEM_5 0 00ba 00aa –1 \
02 1 0 1 ! –1 |
03 2 0 2 " –1 @
04 3 0 3 00b7 –1 #
05 4 0 4 $
06 5 0 5 % –1 20ac
07 6 0 6 & –1 00ac 001e
08 7 0 7 /
09 8 0 8 (
0a 9 0 9 )
0b 0 0 0 =
0c OEM_4 0 ' ?
0d | OEM_6 | 0 | 00a1 | 00bf
10 | Q | 1 | Q | Q
11 | W | 1 | W | W
12 | E | 1 | E | E | –1 | 20ac
13 | R | 1 | R | R
14 | T | 1 | T | T
15 | Y | 1 | Y | Y
16 | U | 1 | U | U
17 | I | 1 | I | I
18 | O | 1 | O | O
19 | P | 1 | P | P
1a OEM_1 0 `@ ^@ 001b [
1b OEM_PLUS 0 + * 001d ]
2b OEM_2 1 00e7 00c7 001c }
1e | A | 1 | A | A
1f | S | 1 | S | S
20 | D | 1 | D | D
21 | F | 1 | F | F
22 | G | 1 | G | G
23 | H | 1 | H | H
24 | J | 1 | J | J
25 | K | 1 | K | K
26 | L | 1 | L | L
27 | OEM_3 | 1 | 00f1 | 00d1
28 OEM_7 0 00b4@ 00a8@ –1 {
2c | Z | 1 | Z | Z
2d | X | 1 | X | X
2e | C | 1 | C | C
2f | V | 1 | V | V
30 | B | 1 | B | B
31 | N | 1 | N | N
32 | M | 1 | M | M
33 OEM_COMMA 0 , ;
34 OEM_PERIOD 0 . :
35 OEM_MINUS 0 - _
56 OEM_102 0 < > 001c
53 DECIMAL 0 . .

Dead Key—0060—Grave
Unicode character pressed
Unicode character result
0061 | 00e0
0065 | 00e8
0069 | 00ec
006f | 00f2
0075 | 00f9
0041 | 00c0
0045 | 00c8
0049 | 00cc
004f | 00d2
0055 | 00d9
0020 | 0060

Dead Key—005e—Circunflejo
Unicode character pressed
Unicode character result
0061 | 00e2
0065 | 00ea
0069 | 00ee
006f | 00f4
0075 | 00fb
0041 | 00c2
0045 | 00ca
0049 | 00ce
004f | 00d4
0055 | 00db
0020 | 005e

Dead Key—00b4—Agudo
Unicode character pressed
Unicode character result
0061 | 00e1
0065 | 00e9
0069 | 00ed
006f | 00f3
0075 | 00fa
0079 | 00fd
0041 | 00c1
0045 | 00c9
0049 | 00cd
004f | 00d3
0055 | 00da
0059 | 00dd
0020 | 00b4

Dead Key—00a8—Diereris
Unicode character pressed
Unicode character result
0061 | 00e4
0065 | 00eb
0069 | 00ef
006f | 00f6
0075 | 00fc
0079 | 00ff
0041 | 00c4
0045 | 00cb
0049 | 00cf
004f | 00d6
0055 | 00dc
0020 | 00a8

Key value
Key name
01 | ESC
0e | RETROCESO
0f | TABULACION
1c | ENTRAR
1d | CTRL
2a | MAYUSCULAS
36 | MAYUSCULAS DERECHA
37 | TECLA DE MULTIPLICACION
38 | ALT
39 | BARRA ESPACIADORA
3a | BLOQ MAYUS
3b | F1
3c | F2
3d | F3
3e | F4
3f | F5
40 | F6
41 | F7
42 | F8
43 | F9
44 | F10
45 | PAUSA
46 | BLOQ DESPL
47 | NUMERO 7
48 | NUMERO 8
49 | NUMERO 9
4a | TECLA DE SUSTRACCION
4b | NUMERO 4
4c | NUMERO 5
4d | NUMERO 6
4e | TECLA DE ADICION
4f | NUMERO 1
50 | NUMERO 2
51 | NUMERO 3
52 | NUMERO 0
53 | TECLA DECIMAL
57 | F11
58 | F12

Key-name extension
1c | INTRO
1d | CTRL DERECHA
35 | TECLA DE DIVISION
37 | IMP PANT
38 | ALT DERECHA
45 | BLOQ NUM
46 | INTERRUMPIR
47 | INICIO
48 | FLECHA ARRIBA
49 | RE PAG
4b | FLECHA IZQUIERDA
4d | FLECHA DERECHA
4f | FIN
50 | FLECHA ABAJO
51 | AV PAG
52 | INSERT
53 | SUPR
54 | <00>
56 | AYUDA
5b | WINDOWS IZQUIERDA
5c | WINDOWS DERECHA
5d | APLICACI\x00D3N


Swedish Keyboard

Scan code
VK_ key
CAP
Character
SHIFT
CTRL
CTRL+
ALT
SHIFT+
CTRL
29 | OEM_5 | 0 | 00a7 | 00bd | 001c
02 1 0 1 !
03 2 0 2 " –1 @
04 3 0 3 # –1 00a3
05 4 0 4 00a4 –1 $
06 5 0 5 % –1 20ac
07 6 0 6 & –1 –1 001e
08 7 0 7 / –1 {
09 8 0 8 ( –1 [
0a 9 0 9 ) –1 ]
0b 0 0 0 = –1 }
0c OEM_PLUS 0 + ? –1 \
0d OEM_4 0 00b4@ `@
10 | Q | 1 | q | Q
11 | W | 1 | w | W
12 | E | 1 | e | E | –1 | 20ac
13 | R | 1 | r | R
14 | T | 1 | t | T
15 | Y | 1 | y | Y
16 | U | 1 | u | U
17 | I | 1 | i | I
18 | O | 1 | o | O
19 | P | 1 | p | P
1a | OEM_6 | 1 | 00e5 | 00c5 | 001b
1b OEM_1 0 00a8@ ^@ 001d ~@
2b OEM_2 0 ' *
1e | A | 1 | a | A
1f | S | 1 | s | S
20 | D | 1 | d | D
21 | F | 1 | f | F
22 | G | 1 | g | G
23 | H | 1 | h | H
24 | J | 1 | j | J
25 | K | 1 | k | K
26 | L | 1 | l | L
27 | OEM_3 | 1 | 00f6 | 00d6
28 | OEM_7 | 1 | 00e4 | 00c4
2c | Z | 1 | z | Z
2d | X | 1 | x | X
2e | C | 1 | c | C
2f | V | 1 | v | V
30 | B | 1 | b | B
31 | N | 1 | n | N
32 | M | 1 | m | M | –1 | 00b5
33 OEM_COMMA 0 , ;
34 OEM_PERIOD 0 . :
35 OEM_MINUS 0 - _ 001f
56 OEM_102 0 < > 001c |
53 DECIMAL 0 , ,

Dead Key—00a8—Omljud
Unicode character pressed
Unicode character result
0061 | 00e4
0065 | 00eb
0069 | 00ef
006f | 00f6
0075 | 00fc
0079 | 00ff
0041 | 00c4
0045 | 00cb
0049 | 00cf
004f | 00d6
0055 | 00dc
0020 | 00a8

Dead Key—005e—Cirkumflex
Unicode character pressed
Unicode character result
0061 | 00e2
0065 | 00ea
0069 | 00ee
006f | 00f4
0075 | 00fb
0041 | 00c2
0045 | 00ca
0049 | 00ce
004f | 00d4
0055 | 00db
0020 | 005e

Dead Key—007e—Tilde
Unicode character pressed
Unicode character result
0061 | 00e3
006f | 00f5
006e | 00f1
0041 | 00c3
004f | 00d5
004e | 00d1
0020 | 007e

Dead Key—00b4—Akut
Unicode character pressed
Unicode character result
0061 | 00e1
0065 | 00e9
0069 | 00ed
006f | 00f3
0075 | 00fa
0079 | 00fd
0041 | 00c1
0045 | 00c9
0049 | 00cd
004f | 00d3
0055 | 00da
0059 | 00dd
0020 | 00b4

Dead Key—0060—Grav
Unicode character pressed
Unicode character result
0061 | 00e0
0065 | 00e8
0069 | 00ec
006f | 00f2
0075 | 00f9
0041 | 00c0
0045 | 00c8
0049 | 00cc
004f | 00d2
0055 | 00d9
0020 | 0060

Key value
Key name
01 | ESC
0e | BACKSTEG
0f | TAB
1c | RETUR
1d | CTRL
2a | SKIFT
36 | H\x00D6GER SKIFT
37 | NUM * (NUMMULT)
38 | ALT
39 | BLANKSTEG
3a | CAPS LOCK
3b | F1
3c | F2
3d | F3
3e | F4
3f | F5
40 | F6
41 | F7
42 | F8
43 | F9
44 | F10
45 | PAUSE
46 | SCROLL LOCK
47 | NUM 7
48 | NUM 8
49 | NUM 9
4a | NUM SUB
4b | NUM 4
4c | NUM 5
4d | NUM 6
4e | NUM PLUS
4f | NUM 1
50 | NUM 2
51 | NUM 3
52 | NUM 0
53 | NUM DECIMAL
54 | Sys Req
57 | F11
58 | F12
7c | F13
7d | F14
7e | F15
7f | F16
80 | F17
81 | F18
82 | F19
83 | F20
84 | F21
85 | F22
86 | F23
87 | F24

Key value
Key-name extension
1c | NUM RETUR
1d | H\x00D6GER CRTL
35 | NUM / (NUM DIVISION)
37 | PRNTSCRN
38 | H\x00D6GER ALT
45 | NUM LOCK
46 | BREAK
47 | HOME
48 | UPPIL
49 | PGUP
4b | V\x00C4NSTERPIL
4d | H\x00D6GERPIL
4f | END
50 | NEDPIL
51 | PGDN
52 | INS
53 | DEL
54 | <00>
56 | HELP
5b | V\x00E4nster Windows
5c | H\x00F6ger Windows
5d | Program


United Kingdom Keyboard

Scan code
VK_ key
CAP
Character
SHIFT
CTRL
SHIFT+CTRL
CTRL+ALT
SHIFT+CTRL+ALT
29 OEM_8 0 ` 00ac –1 –1 00a6
02 1 0 1 !
03 2 0 2 "
04 | 3 | 0 | 3 | 00a3
05 4 0 4 $ –1 –1 20ac
06 5 0 5 %
07 6 0 6 ^ –1 001e
08 7 0 7 &
09 8 0 8 *
0a 9 0 9 (
0b 0 0 0 )
0c OEM_MINUS 0 - _ –1 001f
0d OEM_PLUS 0 = +
10 | Q | 1 | q | Q
11 | W | 1 | w | W
12 | E | 5 | e | E | –1 | –1 | 00e9 | 00c9
13 | R | 1 | r | R
14 | T | 1 | t | T
15 | Y | 1 | y | Y
16 | U | 5 | u | U | –1 | –1 | 00fa | 00da
17 | I | 5 | i | I | –1 | –1 | 00ed | 00cd
18 | O | 5 | o | O | –1 | –1 | 00f3 | 00d3
19 | P | 1 | p | P
1a OEM_4 0 [ { 001b
1b OEM_6 0 ] } 001d
2b OEM_7 0 # ~ 001c
1e | A | 5 | a | A | –1 | –1 | 00e1 | 00c1
1f | S | 1 | s | S
20 | D | 1 | d | D
21 | F | 1 | f | F
22 | G | 1 | g | G
23 | H | 1 | h | H
24 | J | 1 | j | J
25 | K | 1 | k | K
26 | L | 1 | l | L
27 OEM_1 0 ; :
28 OEM_3 0 ' @ –1 0000
2c | Z | 1 | z | Z
2d | X | 1 | x | X
2e | C | 1 | c | C
2f | V | 1 | v | V
30 | B | 1 | b | B
31 | N | 1 | n | N
32 | M | 1 | m | M
33 OEM_COMMA 0 , <
34 OEM_PERIOD 0 . >
35 OEM_2 0 / ?
56 OEM_5 0 \ | 001c
53 DECIMAL 0 . .

Key value
Key name
01 | ESC
0e | BACKSPACE
0f | TAB
1c | ENTER
1d | CTRL
2a | SHIFT
36 | RIGHT SHIFT
37 | NUMMULT
38 | ALT
39 | SPACE
3a | CAPSLOCK
3b | F1
3c | F2
3d | F3
3e | F4
3f | F5
40 | F6
41 | F7
42 | F8
43 | F9
44 | F10
45 | Pause
46 | SCROLL LOCK
47 | NUM 7
48 | NUM 8
49 | NUM 9
4a | NUM SUB
4b | NUM 4
4c | NUM 5
4d | NUM 6
4e | NUM PLUS
4f | NUM 1
50 | NUM 2
51 | NUM 3
52 | NUM 0
53 | NUM DECIMAL
57 | F11
58 | F12

Key value
Key-name extension
1c | NUM ENTER
1d | Right CTRL
35 | NUM DIVIDE
37 | PRINT SCREEN
38 | Right ALT
45 | NUM LOCK
46 | BREAK
47 | HOME
48 | UP
49 | PGUP
4b | LEFT
4d | RIGHT
4f | END
50 | DOWN
51 | PGDOWN
52 | INSERT
53 | DELETE
54 | <00>
56 | Help
5b | Left Windows
5c | Right Windows
5d | Application


United States Keyboard

Scan code
VK_ key
CAP
Character
SHIFT
CTRL
SHIFT+
CTRL
29 OEM_3 0 ` ~
02 1 0 1 !
03 2 0 2 @ –1 0000
04 3 0 3 #
05 4 0 4 $
06 5 0 5 %
07 6 0 6 ^ –1 001e
08 7 0 7 &
09 8 0 8 *
0a 9 0 9 (
0b 0 0 0 )
0c OEM_MINUS 0 - _ –1 001f
0d OEM_PLUS 0 = +
10 | Q | 1 | q | Q
11 | W | 1 | w | W
12 | E | 1 | e | E
13 | R | 1 | r | R
14 | T | 1 | t | T
15 | Y | 1 | y | Y
16 | U | 1 | u | U
17 | I | 1 | i | I
18 | O | 1 | o | O
19 | P | 1 | p | P
1a OEM_4 0 [ { 001b
1b OEM_6 0 ] } 001d
2b OEM_5 0 \ | 001c
1e | A | 1 | a | A
1f | S | 1 | s | S
20 | D | 1 | d | D
21 | F | 1 | f | F
22 | G | 1 | g | G
23 | H | 1 | h | H
24 | J | 1 | j | J
25 | K | 1 | k | K
26 | L | 1 | l | L
27 OEM_1 0 ; :
28 OEM_7 0 ' "
2c | Z | 1 | z | Z
2d | X | 1 | x | X
2e | C | 1 | c | C
2f | V | 1 | v | V
30 | B | 1 | b | B
31 | N | 1 | n | N
32 | M | 1 | m | M
33 OEM_COMMA 0 , <
34 OEM_PERIOD 0 . >
35 OEM_2 0 / ?
56 OEM_102 0 \ | 001c
53 DECIMAL 0 . .

The following table shows the names associated with specific key values

Key value
Key name
01 | ESC
0e | BACKSPACE
0f | TAB
1c | ENTER
1d | CTRL
2a | SHIFT
36 | Right SHIFT
37 | NUM *
38 | ALT
39 | SPACE
3a | CAPS LOCK
3b | F1
3c | F2
3d | F3
3e | F4
3f | F5
40 | F6
41 | F7
42 | F8
43 | F9
44 | F10
45 | PAUSE
46 | SCROLL LOCK
47 | Num 7
48 | Num 8
49 | Num 9
4a | Num -
4b | Num 4
4c | Num 5
4d | Num 6
4e | Num +
4f | Num 1
50 | Num 2
51 | Num 3
52 | Num 0
53 | Num Del
54 | Sys Req
57 | F11
58 | F12
7c | F13
7d | F14
7e | F15
7f | F16
80 | F17
81 | F18
82 | F19
83 | F20
84 | F21
85 | F22
86 | F23
87 | F24


(Untitled)

Topic Not Found

No matching topic was found. Some possible reasons and remedies are as follows:

Reason | Remedy
Destination topic not in the selected active subset. | Set active subset to an appropriate subset or to (Entire Collection).
Link is out-of-date. | Use the index or search function instead.
Link was authored incorrectly. | Use the index or search function instead.
Problems with the MSDN installation. | Uninstall the MSDN Library and then rerun Setup.

See MSDN Library Help for more information on subsets, search, the index, and installation.